1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! Types and traits for registering constants in PHP.
use std::ffi::CString;
use super::flags::GlobalConstantFlags;
use crate::error::Result;
use crate::ffi::{
zend_register_bool_constant, zend_register_double_constant, zend_register_long_constant,
zend_register_string_constant,
};
/// Implemented on types which can be registered as a constant in PHP.
pub trait IntoConst: Sized {
/// Registers a global module constant in PHP, with the value as the content
/// of self. This function _must_ be called in the module startup
/// function, which is called after the module is initialized. The
/// second parameter of the startup function will be the module number.
/// By default, the case-insensitive and persistent flags are set when
/// registering the constant.
///
/// Returns a result containing nothing if the constant was successfully
/// registered.
///
/// # Parameters
///
/// * `name` - The name of the constant.
/// * `module_number` - The module number that we are registering the
/// constant under.
///
/// # Examples
///
/// ```no_run
/// use ext_php_rs::constant::IntoConst;
///
/// pub extern "C" fn startup_function(_type: i32, module_number: i32) -> i32 {
/// 5.register_constant("MY_CONST_NAME", module_number); // MY_CONST_NAME == 5
/// "Hello, world!".register_constant("STRING_CONSTANT", module_number); // STRING_CONSTANT == "Hello, world!"
/// 0
/// }
/// ```
fn register_constant(&self, name: &str, module_number: i32) -> Result<()> {
self.register_constant_flags(
name,
module_number,
GlobalConstantFlags::CaseSensitive | GlobalConstantFlags::Persistent,
)
}
/// Registers a global module constant in PHP, with the value as the content
/// of self. This function _must_ be called in the module startup
/// function, which is called after the module is initialized. The
/// second parameter of the startup function will be the module number.
/// This function allows you to pass any extra flags in if you require.
/// Note that the case-sensitive and persistent flags *are not* set when you
/// use this function, you must set these yourself.
///
/// Returns a result containing nothing if the constant was successfully
/// registered.
///
/// # Parameters
///
/// * `name` - The name of the constant.
/// * `module_number` - The module number that we are registering the
/// constant under.
/// * `flags` - Flags to register the constant with.
///
/// # Examples
///
/// ```no_run
/// use ext_php_rs::{constant::IntoConst, flags::GlobalConstantFlags};
///
/// pub extern "C" fn startup_function(_type: i32, module_number: i32) -> i32 {
/// 42.register_constant_flags("MY_CONST_NAME", module_number, GlobalConstantFlags::Persistent | GlobalConstantFlags::Deprecated);
/// 0
/// }
/// ```
fn register_constant_flags(
&self,
name: &str,
module_number: i32,
flags: GlobalConstantFlags,
) -> Result<()>;
}
impl IntoConst for String {
fn register_constant_flags(
&self,
name: &str,
module_number: i32,
flags: GlobalConstantFlags,
) -> Result<()> {
self.as_str()
.register_constant_flags(name, module_number, flags)
}
}
impl IntoConst for &str {
fn register_constant_flags(
&self,
name: &str,
module_number: i32,
flags: GlobalConstantFlags,
) -> Result<()> {
unsafe {
zend_register_string_constant(
CString::new(name)?.as_ptr(),
name.len() as _,
CString::new(*self)?.as_ptr(),
flags.bits() as _,
module_number,
)
};
Ok(())
}
}
impl IntoConst for bool {
fn register_constant_flags(
&self,
name: &str,
module_number: i32,
flags: GlobalConstantFlags,
) -> Result<()> {
unsafe {
zend_register_bool_constant(
CString::new(name)?.as_ptr(),
name.len() as _,
*self,
flags.bits() as _,
module_number,
)
};
Ok(())
}
}
/// Implements the `IntoConst` trait for a given number type using a given
/// function.
macro_rules! into_const_num {
($type: ty, $fn: expr) => {
impl IntoConst for $type {
fn register_constant_flags(
&self,
name: &str,
module_number: i32,
flags: GlobalConstantFlags,
) -> Result<()> {
Ok(unsafe {
$fn(
CString::new(name)?.as_ptr(),
name.len() as _,
*self as _,
flags.bits() as _,
module_number,
)
})
}
}
};
}
into_const_num!(i8, zend_register_long_constant);
into_const_num!(i16, zend_register_long_constant);
into_const_num!(i32, zend_register_long_constant);
into_const_num!(i64, zend_register_long_constant);
into_const_num!(f32, zend_register_double_constant);
into_const_num!(f64, zend_register_double_constant);