Skip to content

Commit f3ef58c

Browse files
authored
[breaking] add argument and return value type-hints (#187)
1 parent 4d2ad76 commit f3ef58c

File tree

26 files changed

+1485
-131
lines changed

26 files changed

+1485
-131
lines changed

examples/complex/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub fn get_module() -> Module {
5858
// register functions
5959
module
6060
.add_function("complex_say_hello", say_hello)
61-
.argument(Argument::by_val("name"));
61+
.argument(Argument::new("name"));
6262
module.add_function("complex_throw_exception", throw_exception);
6363
module.add_function("complex_get_all_ini", |_: &mut [ZVal]| {
6464
let mut arr = ZArray::new();
@@ -91,7 +91,7 @@ pub fn get_module() -> Module {
9191
Ok(())
9292
},
9393
)
94-
.argument(Argument::by_val("foo"));
94+
.argument(Argument::new("foo"));
9595
module.add_class(foo_class);
9696

9797
// register extra info

examples/hello/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn get_module() -> Module {
3636
// Register function `say_hello`, with one argument `name`.
3737
module
3838
.add_function("say_hello", say_hello)
39-
.argument(Argument::by_val("name"));
39+
.argument(Argument::new("name"));
4040

4141
module
4242
}

examples/http-client/src/client.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn make_client_builder_class(client_class: ClientClass) -> ClassEntity<Clien
3939
*state = builder.timeout(Duration::from_millis(ms as u64));
4040
Ok::<_, phper::Error>(this.to_ref_owned())
4141
})
42-
.argument(Argument::by_val("ms"));
42+
.argument(Argument::new("ms"));
4343

4444
// Inner call the `ClientBuilder::cookie_store`.
4545
class
@@ -50,7 +50,7 @@ pub fn make_client_builder_class(client_class: ClientClass) -> ClassEntity<Clien
5050
*state = builder.cookie_store(enable);
5151
Ok::<_, phper::Error>(this.to_ref_owned())
5252
})
53-
.argument(Argument::by_val("enable"));
53+
.argument(Argument::new("enable"));
5454

5555
// Inner call the `ClientBuilder::build`, and wrap the result `Client` in
5656
// Object.
@@ -85,7 +85,7 @@ pub fn make_client_class(
8585
*object.as_mut_state() = Some(request_builder);
8686
Ok::<_, phper::Error>(object)
8787
})
88-
.argument(Argument::by_val("url"));
88+
.argument(Argument::new("url"));
8989

9090
class
9191
.add_method("post", Visibility::Public, move |this, arguments| {
@@ -96,7 +96,7 @@ pub fn make_client_class(
9696
*object.as_mut_state() = Some(request_builder);
9797
Ok::<_, phper::Error>(object)
9898
})
99-
.argument(Argument::by_val("url"));
99+
.argument(Argument::new("url"));
100100

101101
class
102102
}

examples/http-server/src/response.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pub fn make_response_class() -> ClassEntity<Response<Body>> {
4343

4444
Ok::<_, phper::Error>(())
4545
})
46-
.argument(Argument::by_val("name"))
47-
.argument(Argument::by_val("value"));
46+
.argument(Argument::new("name"))
47+
.argument(Argument::new("value"));
4848

4949
// Register the end method with public visibility, accept `data` parameters.
5050
class
@@ -54,7 +54,7 @@ pub fn make_response_class() -> ClassEntity<Response<Body>> {
5454
*response.body_mut() = arguments[0].expect_z_str()?.to_bytes().to_vec().into();
5555
Ok::<_, phper::Error>(())
5656
})
57-
.argument(Argument::by_val("data"));
57+
.argument(Argument::new("data"));
5858

5959
class
6060
}

examples/http-server/src/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub fn make_server_class(
6767

6868
Ok::<_, phper::Error>(())
6969
})
70-
.arguments([Argument::by_val("host"), Argument::by_val("port")]);
70+
.arguments([Argument::new("host"), Argument::new("port")]);
7171

7272
// Register the onRequest method, with public visibility, insert the handle into
7373
// global ON_REQUEST_HANDLERS map.
@@ -80,7 +80,7 @@ pub fn make_server_class(
8080
});
8181
Ok::<_, phper::Error>(())
8282
})
83-
.argument(Argument::by_val("handle"));
83+
.argument(Argument::new("handle"));
8484

8585
// Register the start method, with public visibility, this method will start and
8686
// http server, listen on the addr, and block.

examples/logging/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn get_module() -> Module {
3232
echo!("Hello, {}!", message);
3333
Ok(())
3434
})
35-
.argument(Argument::by_val("message"));
35+
.argument(Argument::new("message"));
3636

3737
module
3838
.add_function("log_notice", |params: &mut [ZVal]| -> phper::Result<()> {
@@ -45,7 +45,7 @@ pub fn get_module() -> Module {
4545
notice!("Something happened: {}", message);
4646
Ok(())
4747
})
48-
.argument(Argument::by_val("message"));
48+
.argument(Argument::new("message"));
4949

5050
module
5151
.add_function("log_warning", |params: &mut [ZVal]| -> phper::Result<()> {
@@ -58,7 +58,7 @@ pub fn get_module() -> Module {
5858
warning!("Something warning: {}", message);
5959
Ok(())
6060
})
61-
.argument(Argument::by_val("message"));
61+
.argument(Argument::new("message"));
6262

6363
module
6464
.add_function("log_error", |params: &mut [ZVal]| -> phper::Result<()> {
@@ -70,7 +70,7 @@ pub fn get_module() -> Module {
7070
error!("Something gone failed: {}", message);
7171
Ok(())
7272
})
73-
.argument(Argument::by_val("message"));
73+
.argument(Argument::new("message"));
7474

7575
module
7676
.add_function(
@@ -85,7 +85,7 @@ pub fn get_module() -> Module {
8585
Ok(())
8686
},
8787
)
88-
.argument(Argument::by_val("message"));
88+
.argument(Argument::new("message"));
8989

9090
module
9191
}

phper-doc/doc/_02_quick_start/_01_write_your_first_extension/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Full example is <https://github.com/phper-framework/phper/tree/master/examples/h
7979
);
8080

8181
// Register function `say_hello`, with one argument `name`.
82-
module.add_function("say_hello", say_hello).argument(Argument::by_val("name"));
82+
module.add_function("say_hello", say_hello).argument(Argument::new("name"));
8383

8484
module
8585
}

phper-doc/doc/_02_quick_start/_02_write_a_simple_http_client/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ Now let's begin to finish the logic.
211211
*state = builder.timeout(Duration::from_millis(ms as u64));
212212
Ok::<_, phper::Error>(this.to_ref_owned())
213213
})
214-
.argument(Argument::by_val("ms"));
214+
.argument(Argument::new("ms"));
215215

216216
// Inner call the `ClientBuilder::cookie_store`.
217217
class
@@ -222,7 +222,7 @@ Now let's begin to finish the logic.
222222
*state = builder.cookie_store(enable);
223223
Ok::<_, phper::Error>(this.to_ref_owned())
224224
})
225-
.argument(Argument::by_val("enable"));
225+
.argument(Argument::new("enable"));
226226

227227
// Inner call the `ClientBuilder::build`, and wrap the result `Client` in
228228
// Object.

phper-doc/doc/_06_module/_02_register_functions/index.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub fn get_module() -> Module {
1818
let name = arguments[0].expect_z_str()?.to_str()?;
1919
echo!("Hello, {}!\n", name);
2020
Ok(())
21-
}).argument(Argument::by_val("name"));
21+
}).argument(Argument::new("name"));
2222
2323
module
2424
}
@@ -71,7 +71,7 @@ pub fn get_module() -> Module {
7171
let count = arguments[0].expect_mut_z_ref()?;
7272
*count.val_mut().expect_mut_long()? += 100;
7373
Ok(())
74-
}).argument(Argument::by_ref("count"));
74+
}).argument(Argument::new("count").by_ref());
7575
7676
module
7777
}
@@ -80,3 +80,44 @@ pub fn get_module() -> Module {
8080
Here, the argument is registered as
8181
[`Argument::by_ref`](phper::functions::Argument::by_ref). Therefore, the type of
8282
the `count` parameter is no longer long, but a reference.
83+
84+
## Argument and return type modifiers
85+
86+
Arguments can have type-hints, nullability and default values applied. Here we define a function that accepts
87+
a nullable class (in this case, an interface), and a string with a default value:
88+
89+
```rust,no_run
90+
use phper::{modules::Module, php_get_module, functions::Argument, echo};
91+
use phper::types::ArgumentTypeHint;
92+
93+
#[php_get_module]
94+
pub fn get_module() -> Module {
95+
let mut module = Module::new(
96+
env!("CARGO_CRATE_NAME"),
97+
env!("CARGO_PKG_VERSION"),
98+
env!("CARGO_PKG_AUTHORS"),
99+
);
100+
101+
module.add_function("my_function", |_| -> phper::Result<()> {
102+
Ok(())
103+
})
104+
.argument(Argument::new("a_class").with_type_hint(ArgumentTypeHint::ClassEntry(String::from(r"\MyNamespace\MyInterface"))).allow_null())
105+
.argument(Argument::new("name").with_type_hint(ArgumentTypeHint::String).with_default_value("'my_default'"))
106+
.argument(Argument::new("optional_bool").with_type_hint(ArgumentTypeHint::Bool).optional());
107+
108+
module
109+
}
110+
```
111+
112+
The output of `php --re` for this function would look like:
113+
114+
```txt
115+
Function [ <internal:integration> function my_function ] {
116+
117+
- Parameters [3] {
118+
Parameter #0 [ <required> ?class_name $a_class ]
119+
Parameter #1 [ <optional> string $name = 'my_default' ]
120+
Parameter #2 [ <optional> bool $optional_bool = <default> ]
121+
}
122+
}
123+
```

phper-doc/doc/_06_module/_06_register_class/index.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,29 @@ foo.add_static_method(
9999
let name = arguments[0].expect_z_str()?.to_str()?;
100100
Ok::<_, phper::Error>(format!("Hello, {}!\n", name))
101101
},
102-
).argument(Argument::by_val("name"));
102+
).argument(Argument::new("name"));
103+
```
104+
105+
## Argument and return type modifiers
106+
107+
Methods may add argument and return typehints as per functions. For example:
108+
109+
```rust,no_run
110+
use phper::classes::{ClassEntity, ClassEntry, Visibility};
111+
use phper::functions::{Argument, ReturnType};
112+
use phper::types::{ArgumentTypeHint, ReturnTypeHint};
113+
114+
let mut foo = ClassEntity::new("Foo");
115+
foo.add_method(
116+
"test",
117+
Visibility::Public,
118+
|_this, _arguments| -> phper::Result<()> {
119+
Ok(())
120+
},
121+
)
122+
.argument(Argument::new("a_string").with_type_hint(ArgumentTypeHint::String))
123+
.argument(Argument::new("an_interface").with_type_hint(ArgumentTypeHint::ClassEntry(String::from(r"\MyNamespace\MyInterface"))))
124+
.return_type(ReturnType::new(ReturnTypeHint::Bool).allow_null());
103125
```
104126

105127
## Add constants
@@ -148,8 +170,8 @@ class.add_method(
148170
Ok::<_, phper::Error>(())
149171
},
150172
)
151-
.argument(Argument::by_val("key"))
152-
.argument(Argument::by_val("value"));
173+
.argument(Argument::new("key"))
174+
.argument(Argument::new("value"));
153175
```
154176

155177
Equivalent to the following PHP code (hides the implementation details):

phper-doc/doc/_06_module/_07_register_interface/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use phper::objects::StateObj;
6868
use phper::values::ZVal;
6969
7070
let mut foo = InterfaceEntity::new("Foo");
71-
foo.add_method("doSomethings").argument(Argument::by_val("name"));
71+
foo.add_method("doSomethings").argument(Argument::new("name"));
7272
```
7373

7474
Note that abstract has no method body, so you don't need to add the handler to the method.

0 commit comments

Comments
 (0)