Skip to content

Commit 8b3cf30

Browse files
committed
docs(macro): update documentation for builder pattern
1 parent 6786183 commit 8b3cf30

File tree

26 files changed

+432
-189
lines changed

26 files changed

+432
-189
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ Contributions welcome include:
192192
When contributing, please keep in mind the following:
193193
- Create tests if possible.
194194
- Update the documentation if necessary.
195+
- If your change is a [braking change](https://semver.org) a migration guide MUST be included. This
196+
should be placed in the `guide/src/migration-guides` directory.
195197
- Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). We use these to automatically generate changelogs.
196198

197199
Unless you explicitly state otherwise, any contribution intentionally submitted

build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//! The build script for ext-php-rs.
2+
//! This script is responsible for generating the bindings to the PHP Zend API.
3+
//! It also checks the PHP version for compatibility with ext-php-rs and sets
4+
//! configuration flags accordingly.
15
#[cfg_attr(windows, path = "windows_build.rs")]
26
#[cfg_attr(not(windows), path = "unix_build.rs")]
37
mod impl_;
@@ -18,6 +22,7 @@ use impl_::Provider;
1822
const MIN_PHP_API_VER: u32 = 20200930;
1923
const MAX_PHP_API_VER: u32 = 20240924;
2024

25+
/// Provides information about the PHP installation.
2126
pub trait PHPProvider<'a>: Sized {
2227
/// Create a new PHP provider.
2328
fn new(info: &'a PHPInfo) -> Result<Self>;
@@ -75,9 +80,11 @@ fn find_php() -> Result<PathBuf> {
7580
})
7681
}
7782

83+
/// Output of `php -i`.
7884
pub struct PHPInfo(String);
7985

8086
impl PHPInfo {
87+
/// Get the PHP info.
8188
pub fn get(php: &Path) -> Result<Self> {
8289
let cmd = Command::new(php)
8390
.arg("-i")
@@ -100,25 +107,29 @@ impl PHPInfo {
100107
.try_into()
101108
}
102109

110+
/// Checks if thread safety is enabled.
103111
pub fn thread_safety(&self) -> Result<bool> {
104112
Ok(self
105113
.get_key("Thread Safety")
106114
.context("Could not find thread safety of PHP")?
107115
== "enabled")
108116
}
109117

118+
/// Checks if PHP was built with debug.
110119
pub fn debug(&self) -> Result<bool> {
111120
Ok(self
112121
.get_key("Debug Build")
113122
.context("Could not find debug build of PHP")?
114123
== "yes")
115124
}
116125

126+
/// Get the php version.
117127
pub fn version(&self) -> Result<&str> {
118128
self.get_key("PHP Version")
119129
.context("Failed to get PHP version")
120130
}
121131

132+
/// Get the zend version.
122133
pub fn zend_version(&self) -> Result<u32> {
123134
self.get_key("PHP API")
124135
.context("Failed to get Zend version")

crates/macros/src/function.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ impl<'a> Function<'a> {
134134
// `handler` impl
135135
let required_arg_names: Vec<_> = required.iter().map(|arg| arg.name).collect();
136136
let not_required_arg_names: Vec<_> = not_required.iter().map(|arg| arg.name).collect();
137-
let arg_declerations = self
137+
let arg_declarations = self
138138
.args
139139
.typed
140140
.iter()
141-
.map(TypedArg::arg_decleration)
141+
.map(TypedArg::arg_declaration)
142142
.collect::<Result<Vec<_>>>()?;
143143
let arg_accessors = self.args.typed.iter().map(|arg| {
144144
arg.accessor(|e| {
@@ -248,7 +248,7 @@ impl<'a> Function<'a> {
248248
) {
249249
use ::ext_php_rs::convert::IntoZval;
250250

251-
#(#arg_declerations)*
251+
#(#arg_declarations)*
252252
let result = {
253253
#result
254254
};
@@ -308,11 +308,11 @@ impl<'a> Function<'a> {
308308

309309
let required_arg_names: Vec<_> = required.iter().map(|arg| arg.name).collect();
310310
let not_required_arg_names: Vec<_> = not_required.iter().map(|arg| arg.name).collect();
311-
let arg_declerations = self
311+
let arg_declarations = self
312312
.args
313313
.typed
314314
.iter()
315-
.map(TypedArg::arg_decleration)
315+
.map(TypedArg::arg_declaration)
316316
.collect::<Result<Vec<_>>>()?;
317317
let arg_accessors = self.args.typed.iter().map(|arg| {
318318
arg.accessor(
@@ -329,7 +329,7 @@ impl<'a> Function<'a> {
329329
::ext_php_rs::class::ConstructorMeta {
330330
constructor: {
331331
fn inner(ex: &mut ::ext_php_rs::zend::ExecuteData) -> ::ext_php_rs::class::ConstructorResult<#class> {
332-
#(#arg_declerations)*
332+
#(#arg_declarations)*
333333
let parse = ex.parser()
334334
#(.arg(&mut #required_arg_names))*
335335
.not_required()
@@ -515,9 +515,9 @@ impl TypedArg<'_> {
515515
ty
516516
}
517517

518-
/// Returns a token stream containing an argument decleration, where the
518+
/// Returns a token stream containing an argument declaration, where the
519519
/// name of the variable holding the arg is the name of the argument.
520-
fn arg_decleration(&self) -> Result<TokenStream> {
520+
fn arg_declaration(&self) -> Result<TokenStream> {
521521
let name = self.name;
522522
let val = self.arg_builder()?;
523523
Ok(quote! {

crates/macros/src/impl_.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub enum RenameRule {
1313
/// Methods won't be renamed.
1414
#[darling(rename = "none")]
1515
None,
16-
/// Methods will be conveted to camelCase.
16+
/// Methods will be converted to camelCase.
1717
#[darling(rename = "camelCase")]
1818
#[default]
1919
Camel,

crates/macros/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ use syn::{
1919

2020
extern crate proc_macro;
2121

22+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
23+
// The guide tests will cover these macros.
24+
#[cfg(not(doctest))]
2225
#[lsp_doc("guide/src/macros/classes.md")]
2326
#[proc_macro_attribute]
2427
pub fn php_class(args: TokenStream, input: TokenStream) -> TokenStream {
@@ -30,6 +33,9 @@ pub fn php_class(args: TokenStream, input: TokenStream) -> TokenStream {
3033
.into()
3134
}
3235

36+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
37+
// The guide tests will cover these macros.
38+
#[cfg(not(doctest))]
3339
#[lsp_doc("guide/src/macros/function.md")]
3440
#[proc_macro_attribute]
3541
pub fn php_function(args: TokenStream, input: TokenStream) -> TokenStream {
@@ -41,6 +47,9 @@ pub fn php_function(args: TokenStream, input: TokenStream) -> TokenStream {
4147
.into()
4248
}
4349

50+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
51+
// The guide tests will cover these macros.
52+
#[cfg(not(doctest))]
4453
#[lsp_doc("guide/src/macros/constant.md")]
4554
#[proc_macro_attribute]
4655
pub fn php_const(_args: TokenStream, input: TokenStream) -> TokenStream {
@@ -49,6 +58,9 @@ pub fn php_const(_args: TokenStream, input: TokenStream) -> TokenStream {
4958
constant::parser(input).into()
5059
}
5160

61+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
62+
// The guide tests will cover these macros.
63+
#[cfg(not(doctest))]
5264
#[lsp_doc("guide/src/macros/module.md")]
5365
#[proc_macro_attribute]
5466
pub fn php_module(args: TokenStream, input: TokenStream) -> TokenStream {
@@ -60,6 +72,9 @@ pub fn php_module(args: TokenStream, input: TokenStream) -> TokenStream {
6072
.into()
6173
}
6274

75+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
76+
// The guide tests will cover these macros.
77+
#[cfg(not(doctest))]
6378
#[lsp_doc("guide/src/macros/impl.md")]
6479
#[proc_macro_attribute]
6580
pub fn php_impl(args: TokenStream, input: TokenStream) -> TokenStream {
@@ -71,6 +86,9 @@ pub fn php_impl(args: TokenStream, input: TokenStream) -> TokenStream {
7186
.into()
7287
}
7388

89+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
90+
// The guide tests will cover these macros.
91+
#[cfg(not(doctest))]
7492
#[lsp_doc("guide/src/macros/extern.md")]
7593
#[proc_macro_attribute]
7694
pub fn php_extern(_: TokenStream, input: TokenStream) -> TokenStream {
@@ -81,6 +99,9 @@ pub fn php_extern(_: TokenStream, input: TokenStream) -> TokenStream {
8199
.into()
82100
}
83101

102+
// Not included in the doc tests, as they depend on `ext-php-rs` being available.
103+
// The guide tests will cover these macros.
104+
#[cfg(not(doctest))]
84105
#[lsp_doc("guide/src/macros/zval_convert.md")]
85106
#[proc_macro_derive(ZvalConvert)]
86107
pub fn zval_convert_derive(input: TokenStream) -> TokenStream {
@@ -91,6 +112,7 @@ pub fn zval_convert_derive(input: TokenStream) -> TokenStream {
91112
.into()
92113
}
93114

115+
#[cfg(not(doctest))]
94116
/// Defines an `extern` function with the Zend fastcall convention based on
95117
/// operating system.
96118
///

guide/src/SUMMARY.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
- [Async futures](./macros/async_impl.md)
2828
- [Macros](./macros/index.md)
2929
- [Module](./macros/module.md)
30-
- [Module Startup Function](./macros/module_startup.md)
3130
- [Function](./macros/function.md)
3231
- [Classes](./macros/classes.md)
3332
- [`impl`s](./macros/impl.md)
@@ -37,3 +36,7 @@
3736
- [`ZvalConvert`](./macros/zval_convert.md)
3837
- [Exceptions](./exceptions.md)
3938
- [INI Settings](./ini-settings.md)
39+
40+
# Migration Guides
41+
---
42+
[v0.14](./migration-guides/v0.14.md)

guide/src/getting-started/hello_world.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,16 @@ Let's actually write the extension code now. We start by importing the
5757
basic extension. We will then write our basic `hello_world` function, which will
5858
take a string argument for the callers name, and we will return another string.
5959
Finally, we write a `get_module` function which is used by PHP to find out about
60-
your module. The `#[php_module]` attribute automatically registers your new
61-
function so we don't need to do anything except return the `ModuleBuilder` that
62-
we were given.
60+
your module. We must provide the defined function to the given `ModuleBuilder`
61+
and then return the same object.
6362

64-
We also need to enable the `abi_vectorcall` feature when compiling for Windows.
65-
This is a nightly-only feature so it is recommended to use the `#[cfg_attr]`
66-
macro to not enable the feature on other operating systems.
63+
We also need to enable the `abi_vectorcall` feature when compiling for Windows
64+
(the first line). This is a nightly-only feature so it is recommended to use
65+
the `#[cfg_attr]` macro to not enable the feature on other operating systems.
6766

68-
```rust,ignore
67+
```rust,no_run
6968
#![cfg_attr(windows, feature(abi_vectorcall))]
69+
# extern crate ext_php_rs;
7070
use ext_php_rs::prelude::*;
7171
7272
#[php_function]
@@ -76,8 +76,9 @@ pub fn hello_world(name: &str) -> String {
7676
7777
#[php_module]
7878
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
79-
module
79+
module.function(wrap_function!(hello_world))
8080
}
81+
# fn main() {}
8182
```
8283

8384
## Building the extension

guide/src/ini-settings.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,22 @@ All PHP INI definitions must be registered with PHP to get / set their values vi
1414
# use ext_php_rs::zend::IniEntryDef;
1515
# use ext_php_rs::flags::IniEntryPermission;
1616
17-
#[php_startup]
18-
pub fn startup_function(ty: i32, module_number: i32) {
17+
pub fn startup(ty: i32, mod_num: i32) -> i32 {
1918
let ini_entries: Vec<IniEntryDef> = vec![
2019
IniEntryDef::new(
2120
"my_extension.display_emoji".to_owned(),
2221
"yes".to_owned(),
2322
IniEntryPermission::All,
2423
),
2524
];
26-
IniEntryDef::register(ini_entries, module_number);
25+
IniEntryDef::register(ini_entries, mod_num);
26+
27+
0
28+
}
29+
30+
#[php_module(startup = "startup")]
31+
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
32+
module
2733
}
2834
# fn main() {}
2935
```
@@ -35,14 +41,22 @@ The INI values are stored as part of the `GlobalExecutor`, and can be accessed v
3541
```rust,no_run
3642
# #![cfg_attr(windows, feature(abi_vectorcall))]
3743
# extern crate ext_php_rs;
38-
# use ext_php_rs::prelude::*;
39-
# use ext_php_rs::zend::ExecutorGlobals;
44+
use ext_php_rs::{
45+
prelude::*,
46+
zend::ExecutorGlobals,
47+
};
4048
41-
#[php_startup]
42-
pub fn startup_function(ty: i32, module_number: i32) {
49+
pub fn startup(ty: i32, mod_num: i32) -> i32 {
4350
// Get all INI values
4451
let ini_values = ExecutorGlobals::get().ini_values(); // HashMap<String, Option<String>>
4552
let my_ini_value = ini_values.get("my_extension.display_emoji"); // Option<Option<String>>
53+
54+
0
55+
}
56+
57+
#[php_module(startup = "startup")]
58+
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
59+
module
4660
}
4761
# fn main() {}
4862
```

guide/src/introduction.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Our main goal is to **make extension development easier.**
3232
guaranteed while we are at major version `0`, which is for the foreseeable
3333
future. It's recommended to lock the version at the patch level.
3434

35+
When introducing breaking changes a migration guide will be provided in this
36+
guide.
37+
3538
## Documentation
3639

3740
- This guide!

0 commit comments

Comments
 (0)