Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc66a28f

Browse files
authored
feat: Add preliminary support for enums (#201)
1 parent1598925 commitc66a28f

File tree

17 files changed

+781
-13
lines changed

17 files changed

+781
-13
lines changed

‎Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎phper-build/src/lib.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,32 +24,36 @@ pub fn register_all() {
2424
pubfnregister_configures(){
2525
// versions
2626
println!(
27-
"cargo:rustc-cfg=phper_major_version=\"{}\"",
27+
"cargo::rustc-cfg=phper_major_version=\"{}\"",
2828
PHP_MAJOR_VERSION
2929
);
3030
println!(
31-
"cargo:rustc-cfg=phper_minor_version=\"{}\"",
31+
"cargo::rustc-cfg=phper_minor_version=\"{}\"",
3232
PHP_MINOR_VERSION
3333
);
3434
println!(
35-
"cargo:rustc-cfg=phper_release_version=\"{}\"",
35+
"cargo::rustc-cfg=phper_release_version=\"{}\"",
3636
PHP_RELEASE_VERSION
3737
);
3838

3939
ifPHP_DEBUG !=0{
40-
println!("cargo:rustc-cfg=phper_debug");
40+
println!("cargo::rustc-cfg=phper_debug");
4141
}
4242

4343
ifUSING_ZTS !=0{
44-
println!("cargo:rustc-cfg=phper_zts");
44+
println!("cargo::rustc-cfg=phper_zts");
45+
}
46+
47+
ifPHP_VERSION_ID >=80100{
48+
println!("cargo::rustc-cfg=phper_enum_supported");
4549
}
4650
}
4751

4852
/// Register link arguments for os-specified situation.
4953
pubfnregister_link_args(){
5054
#[cfg(target_os ="macos")]
5155
{
52-
println!("cargo:rustc-link-arg=-undefined");
53-
println!("cargo:rustc-link-arg=dynamic_lookup");
56+
println!("cargo::rustc-link-arg=-undefined");
57+
println!("cargo::rustc-link-arg=dynamic_lookup");
5458
}
5559
}

‎phper-doc/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,11 @@ phper = { workspace = true }
2525
[dev-dependencies]
2626
thiserror ="2.0.11"
2727
reqwest = {version ="0.12.12",features = ["blocking","cookies"] }
28+
29+
[build-dependencies]
30+
phper-build = {workspace =true }
31+
32+
[lints.rust]
33+
unexpected_cfgs = {level ="warn",check-cfg = [
34+
'cfg(phper_enum_supported)',
35+
] }
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
#Register Enums
2+
3+
>PHP 8.1 and above introduced the Enum functionality.`PHPER` allowing you to create PHP enums using Rust code.
4+
5+
In`PHPER`, you can use the[`add_enum`](phper::modules::Module::add_enum) method to register enums.
6+
According to PHP's enum specification,`PHPER` supports three types of enums:
7+
8+
1. Pure enums (without values)
9+
2. Integer-backed enums
10+
3. String-backed enums
11+
12+
##Creating Pure Enums
13+
14+
Pure enums are the simplest type of enum, having only member names without associated values. Use`EnumEntity<()>` to create a pure enum (or simply use`EnumEntity::new()` since`()` is the default type parameter).
15+
16+
```rust,no_run
17+
use phper::{modules::Module, php_get_module, enums::EnumEntity, classes::Visibility};
18+
19+
#[php_get_module]
20+
pub fn get_module() -> Module {
21+
let mut module = Module::new(
22+
env!("CARGO_CRATE_NAME"),
23+
env!("CARGO_PKG_VERSION"),
24+
env!("CARGO_PKG_AUTHORS"),
25+
);
26+
27+
// Create a pure enum
28+
let mut status = EnumEntity::new("Status");
29+
30+
// Add enum cases (without values)
31+
status.add_case("PENDING", ());
32+
status.add_case("ACTIVE", ());
33+
status.add_case("INACTIVE", ());
34+
35+
// Register the enum to the module
36+
module.add_enum(status);
37+
38+
module
39+
}
40+
```
41+
42+
This is equivalent to the following PHP code:
43+
44+
```php
45+
enum Status {
46+
case PENDING;
47+
case ACTIVE;
48+
case INACTIVE;
49+
}
50+
```
51+
52+
##Creating Integer-Backed Enums
53+
54+
Integer-backed enums associate each enum member with an integer value. Use`EnumEntity<i64>` to create an integer-backed enum.
55+
56+
```rust,no_run
57+
use phper::{modules::Module, php_get_module, enums::EnumEntity};
58+
59+
#[php_get_module]
60+
pub fn get_module() -> Module {
61+
let mut module = Module::new(
62+
env!("CARGO_CRATE_NAME"),
63+
env!("CARGO_PKG_VERSION"),
64+
env!("CARGO_PKG_AUTHORS"),
65+
);
66+
67+
// Create an integer-backed enum
68+
let mut level = EnumEntity::<i64>::new("Level");
69+
70+
// Add enum cases with their associated integer values
71+
level.add_case("LOW", 1);
72+
level.add_case("MEDIUM", 5);
73+
level.add_case("HIGH", 10);
74+
75+
// Register the enum to the module
76+
module.add_enum(level);
77+
78+
module
79+
}
80+
```
81+
82+
This is equivalent to the following PHP code:
83+
84+
```php
85+
enum Level: int {
86+
case LOW = 1;
87+
case MEDIUM = 5;
88+
case HIGH = 10;
89+
}
90+
```
91+
92+
##Creating String-Backed Enums
93+
94+
String-backed enums associate each enum member with a string value. Use`EnumEntity<String>` to create a string-backed enum.
95+
96+
```rust,no_run
97+
use phper::{modules::Module, php_get_module, enums::EnumEntity};
98+
99+
#[php_get_module]
100+
pub fn get_module() -> Module {
101+
let mut module = Module::new(
102+
env!("CARGO_CRATE_NAME"),
103+
env!("CARGO_PKG_VERSION"),
104+
env!("CARGO_PKG_AUTHORS"),
105+
);
106+
107+
// Create a string-backed enum
108+
let mut color = EnumEntity::<String>::new("Color");
109+
110+
// Add enum cases with their associated string values
111+
color.add_case("RED", "FF0000".to_string());
112+
color.add_case("GREEN", "00FF00".to_string());
113+
color.add_case("BLUE", "0000FF".to_string());
114+
115+
// Register the enum to the module
116+
module.add_enum(color);
117+
118+
module
119+
}
120+
```
121+
122+
This is equivalent to the following PHP code:
123+
124+
```php
125+
enum Color: string {
126+
case RED = "FF0000";
127+
case GREEN = "00FF00";
128+
case BLUE = "0000FF";
129+
}
130+
```
131+
132+
##Adding Constants
133+
134+
Enums can contain constants. Use the`add_constant` method to add constants to an enum.
135+
136+
```rust,no_run
137+
use phper::{modules::Module, php_get_module, enums::EnumEntity};
138+
139+
let mut status = EnumEntity::new("Status");
140+
141+
// Add enum cases
142+
status.add_case("PENDING", ());
143+
status.add_case("ACTIVE", ());
144+
145+
// Add constants
146+
status.add_constant("VERSION", "1.0.0");
147+
status.add_constant("MAX_ATTEMPTS", 3);
148+
```
149+
150+
This is equivalent to the following PHP code:
151+
152+
```php
153+
enum Status {
154+
case PENDING;
155+
case ACTIVE;
156+
157+
public const VERSION = "1.0.0";
158+
public const MAX_ATTEMPTS = 3;
159+
}
160+
```
161+
162+
##Adding Static Methods
163+
164+
You can add static methods to enums. Use the`add_static_method` method to add a static method to an enum.
165+
166+
```rust,no_run
167+
use phper::{modules::Module, php_get_module, enums::EnumEntity, classes::Visibility};
168+
use std::convert::Infallible;
169+
170+
let mut status = EnumEntity::new("Status");
171+
172+
// Add enum cases
173+
status.add_case("PENDING", ());
174+
status.add_case("ACTIVE", ());
175+
176+
// Add static method
177+
status.add_static_method("getDescription", Visibility::Public, |_| {
178+
Ok::<_, Infallible>("Status enumeration for tracking item states")
179+
});
180+
```
181+
182+
This is equivalent to the following PHP code:
183+
184+
```php
185+
enum Status {
186+
case PENDING;
187+
case ACTIVE;
188+
189+
public static function getDescription(): string {
190+
return "Status enumeration for tracking item states";
191+
}
192+
}
193+
```
194+
195+
##Implementing Interfaces
196+
197+
You can make enums implement interfaces. Use the`implements` method to make an enum implement a specific interface.
198+
199+
```rust,no_run
200+
use phper::{modules::Module, php_get_module, enums::EnumEntity, classes::Interface};
201+
202+
let mut color = EnumEntity::<String>::new("Color");
203+
204+
// Add enum cases
205+
color.add_case("RED", "FF0000".to_string());
206+
color.add_case("GREEN", "00FF00".to_string());
207+
208+
// Implement interface
209+
color.implements(Interface::from_name("JsonSerializable"));
210+
211+
// Note: You need to add necessary methods to satisfy interface requirements
212+
// For example, JsonSerializable interface requires the implementation of jsonSerialize method
213+
```
214+
215+
##Using Built-in Enum Methods
216+
217+
PHP enums come with some built-in methods. Pure enums (`UnitEnum`) have the`cases()` method, while backed enums (`BackedEnum`) additionally have the`from()` and`tryFrom()` methods.
218+
219+
```php
220+
// Examples of using built-in methods in PHP
221+
$allCases = Color::cases(); // Returns an array of all enum cases
222+
223+
// Only available for backed enums
224+
$colorFromValue = Color::from("FF0000"); // Returns RED
225+
$colorOrNull = Color::tryFrom("INVALID"); // Returns null (when the value doesn't exist)
226+
```
227+
228+
##Complete Example
229+
230+
Here's a comprehensive example using both pure and backed enums:
231+
232+
```rust,no_run
233+
use phper::{
234+
modules::Module,
235+
php_get_module,
236+
enums::EnumEntity,
237+
classes::Visibility
238+
};
239+
use std::convert::Infallible;
240+
241+
#[php_get_module]
242+
pub fn get_module() -> Module {
243+
let mut module = Module::new(
244+
env!("CARGO_CRATE_NAME"),
245+
env!("CARGO_PKG_VERSION"),
246+
env!("CARGO_PKG_AUTHORS"),
247+
);
248+
249+
// Pure enum
250+
let mut status = EnumEntity::new("Status");
251+
status.add_case("PENDING", ());
252+
status.add_case("ACTIVE", ());
253+
status.add_case("INACTIVE", ());
254+
status.add_constant("VERSION", "1.0.0");
255+
status.add_static_method("getDescription", Visibility::Public, |_| {
256+
Ok::<_, Infallible>("Status enumeration")
257+
});
258+
259+
// Integer-backed enum
260+
let mut level = EnumEntity::<i64>::new("Level");
261+
level.add_case("LOW", 1);
262+
level.add_case("MEDIUM", 5);
263+
level.add_case("HIGH", 10);
264+
265+
// Register enums to the module
266+
module.add_enum(status);
267+
module.add_enum(level);
268+
269+
module
270+
}
271+
```
272+
273+
>**Note**: PHP enums require PHP 8.1 or higher. Make sure your extension sets the correct PHP version requirements.

‎phper-doc/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ pub mod _06_module {
6969

7070
#[doc =include_str!("../doc/_06_module/_07_register_interface/index.md")]
7171
pubmod _07_register_interface{}
72+
73+
#[cfg(phper_enum_supported)]
74+
#[doc =include_str!("../doc/_06_module/_08_register_enum/index.md")]
75+
pubmod _08_register_enum{}
7276
}
7377

7478
/// TODO

‎phper-sys/php_wrapper.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include<zend_observer.h>
2323
#endif
2424

25+
#ifPHP_VERSION_ID >=80100
26+
#include<zend_enum.h>
27+
#endif
28+
2529
typedefZEND_INI_MH(phper_zend_ini_mh);
2630

2731
typedefzend_class_entry*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp