Skip to content

Commit 042d044

Browse files
committed
Refactor TransformIniValue.
1 parent 74f1316 commit 042d044

File tree

7 files changed

+51
-53
lines changed

7 files changed

+51
-53
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jobs:
3333
- name: Checkout
3434
uses: actions/checkout@v2
3535

36+
- name: Install libclang
37+
run: sudo apt-get install -y libclang-10-dev
38+
3639
- name: Setup PHP
3740
uses: shivammathur/setup-php@v2
3841
with:

examples/hello/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,13 @@ pub fn get_module() -> Module {
6363

6464
// register classes
6565
let mut foo_class = DynamicClass::new("FooClass");
66-
// foo_class.add_property("foo", Visibility::Public, 100);
67-
foo_class.add_property("foo", Visibility::Public, 100);
66+
foo_class.add_property("foo", Visibility::Private, 100);
6867
foo_class.add_method(
6968
"getFoo",
7069
Visibility::Public,
71-
|this: &mut Object<()>, _: &mut [Val]| -> phper::Result<Val> {
70+
|this: &mut Object<()>, _: &mut [Val]| {
7271
let prop = this.get_property("foo");
73-
Ok(Val::new(prop.as_string_value()?))
72+
Ok::<_, phper::Error>(prop.as_string_value()?)
7473
},
7574
vec![],
7675
);

examples/hello/tests/php/test.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@
1212
assert_eq($e->getMessage(), "I am sorry");
1313
}
1414

15-
var_dump(ini_get_all());
16-
die();
17-
1815
assert_eq(hello_get_all_ini(), [
1916
"hello.enable" => false,
2017
"hello.description" => "hello world.",
2118
]);
2219

2320
$foo = new FooClass();
24-
assert_eq($foo->getFoo(), 100);
21+
assert_eq($foo->getFoo(), "100");
2522

2623
$foo->setFoo("Hello");
2724
assert_eq($foo->getFoo(), "Hello");

phper-macros/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ The proc-macros for [phper](https://crates.io/crates/phper).
88
[Unlicense](https://github.com/jmjoy/phper/blob/master/LICENSE).
99
*/
1010

11+
// TODO Write a bridge macro for easy usage about register functions and classes.
12+
1113
mod alloc;
1214
mod inner;
1315
mod log;

phper/src/classes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ impl PropertyEntity {
347347
zend_declare_property_bool(ce, name, name_length, *b as zend_long, access_type);
348348
}
349349
Scalar::I64(i) => {
350-
zend_declare_property_bool(ce, name, name_length, *i, access_type);
350+
zend_declare_property_long(ce, name, name_length, *i, access_type);
351351
}
352352
Scalar::F64(f) => {
353353
zend_declare_property_double(ce, name, name_length, *f, access_type);

phper/src/ini.rs

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -79,104 +79,104 @@ pub enum Policy {
7979
System = PHP_INI_SYSTEM,
8080
}
8181

82-
pub trait TransformIniValue: ToString + 'static {
83-
fn on_modify(&self) -> OnModify;
82+
/// The Type which can transform to an ini value.
83+
///
84+
/// Be careful that the size of `arg2` must litter than size of `usize`.
85+
///
86+
/// TODO Add a size compare with usize trait bound, after const generic supports.
87+
pub trait TransformIniValue: Sized + ToString + 'static {
88+
fn on_modify() -> OnModify;
8489

85-
unsafe fn transform(&self, data: usize) -> Option<*mut c_void>;
90+
unsafe fn transform(data: usize) -> Option<Self>;
8691

87-
fn arg2_type(&self) -> TypeId;
92+
fn arg2_type() -> TypeId;
8893

89-
fn arg2_size(&self) -> usize;
94+
fn arg2_size() -> usize;
9095

9196
fn to_text(&self) -> String {
9297
self.to_string()
9398
}
9499
}
95100

96101
impl TransformIniValue for bool {
97-
fn on_modify(&self) -> OnModify {
102+
fn on_modify() -> OnModify {
98103
Some(OnUpdateBool)
99104
}
100105

101-
unsafe fn transform(&self, data: usize) -> Option<*mut c_void> {
102-
let b = data != 0;
103-
Some(Box::into_raw(Box::new(b)).cast())
106+
unsafe fn transform(data: usize) -> Option<Self> {
107+
Some(data != 0)
104108
}
105109

106-
fn arg2_type(&self) -> TypeId {
110+
fn arg2_type() -> TypeId {
107111
TypeId::of::<bool>()
108112
}
109113

110-
fn arg2_size(&self) -> usize {
114+
fn arg2_size() -> usize {
111115
size_of::<bool>()
112116
}
113117
}
114118

115119
impl TransformIniValue for i64 {
116-
fn on_modify(&self) -> OnModify {
120+
fn on_modify() -> OnModify {
117121
Some(OnUpdateLong)
118122
}
119123

120-
unsafe fn transform(&self, data: usize) -> Option<*mut c_void> {
121-
let i = data as i64;
122-
Some(Box::into_raw(Box::new(i)).cast())
124+
unsafe fn transform(data: usize) -> Option<Self> {
125+
Some(data as i64)
123126
}
124127

125-
fn arg2_type(&self) -> TypeId {
128+
fn arg2_type() -> TypeId {
126129
TypeId::of::<i64>()
127130
}
128131

129-
fn arg2_size(&self) -> usize {
132+
fn arg2_size() -> usize {
130133
size_of::<i64>()
131134
}
132135
}
133136

134137
impl TransformIniValue for f64 {
135-
fn on_modify(&self) -> OnModify {
138+
fn on_modify() -> OnModify {
136139
Some(OnUpdateReal)
137140
}
138141

139-
unsafe fn transform(&self, data: usize) -> Option<*mut c_void> {
140-
let f = data as f64;
141-
Some(Box::into_raw(Box::new(f)).cast())
142+
unsafe fn transform(data: usize) -> Option<Self> {
143+
Some(data as f64)
142144
}
143145

144-
fn arg2_type(&self) -> TypeId {
146+
fn arg2_type() -> TypeId {
145147
TypeId::of::<i64>()
146148
}
147149

148-
fn arg2_size(&self) -> usize {
150+
fn arg2_size() -> usize {
149151
size_of::<i64>()
150152
}
151153
}
152154

153155
impl TransformIniValue for String {
154-
fn on_modify(&self) -> OnModify {
156+
fn on_modify() -> OnModify {
155157
Some(OnUpdateString)
156158
}
157159

158-
unsafe fn transform(&self, data: usize) -> Option<*mut c_void> {
160+
unsafe fn transform(data: usize) -> Option<Self> {
159161
let ptr = data as *mut c_char;
160-
CStr::from_ptr(ptr)
161-
.to_str()
162-
.ok()
163-
.map(|s| Box::into_raw(Box::new(s.to_owned())).cast())
162+
CStr::from_ptr(ptr).to_str().ok().map(|s| s.to_owned())
164163
}
165164

166-
fn arg2_type(&self) -> TypeId {
165+
fn arg2_type() -> TypeId {
167166
TypeId::of::<*mut c_char>()
168167
}
169168

170-
fn arg2_size(&self) -> usize {
169+
fn arg2_size() -> usize {
171170
size_of::<*mut c_char>()
172171
}
173172
}
174173

175174
pub(crate) struct IniEntity {
176175
name: String,
177176
value: usize,
177+
value_type_id: TypeId,
178178
default_value: String,
179-
transform: Box<dyn TransformIniValue>,
179+
on_modify: OnModify,
180180
policy: Policy,
181181
}
182182

@@ -186,35 +186,30 @@ impl IniEntity {
186186
default_value: T,
187187
policy: Policy,
188188
) -> Self {
189-
assert!(default_value.arg2_size() <= size_of::<usize>());
189+
assert!(<T>::arg2_size() <= size_of::<usize>());
190190
Self {
191191
name: name.to_string(),
192192
value: 0,
193+
value_type_id: <T>::arg2_type(),
193194
default_value: default_value.to_text(),
194-
transform: Box::new(default_value),
195+
on_modify: <T>::on_modify(),
195196
policy,
196197
}
197198
}
198199

199200
pub(crate) fn value<T: TransformIniValue>(&self) -> Option<T> {
200-
if self.transform.arg2_type() != TypeId::of::<T>() {
201+
if self.value_type_id != <T>::arg2_type() {
201202
None
202203
} else {
203-
unsafe {
204-
let ptr = self.transform.transform(self.value);
205-
ptr.map(|ptr| {
206-
let b = Box::from_raw(ptr as *mut T);
207-
*b
208-
})
209-
}
204+
unsafe { <T>::transform(self.value) }
210205
}
211206
}
212207

213208
pub(crate) fn entry(&mut self) -> zend_ini_entry_def {
214209
create_ini_entry_ex(
215210
&self.name,
216211
&self.default_value,
217-
self.transform.on_modify(),
212+
self.on_modify,
218213
self.policy as u32,
219214
&mut self.value as *mut _ as *mut c_void,
220215
)

phper/src/types.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use derive_more::From;
55
use num_traits::cast::FromPrimitive;
66
use std::{ffi::CStr, os::raw::c_int};
77

8+
/// TODO Refactor to a struct rather than enum, because it's so complex than the type have bit flag.
89
#[derive(FromPrimitive, PartialEq, Clone, Copy)]
910
#[repr(u32)]
1011
#[non_exhaustive]
@@ -83,8 +84,9 @@ impl From<u32> for Type {
8384
}
8485
}
8586

86-
pub(crate) fn get_type_by_const(t: u32) -> crate::Result<String> {
87+
pub(crate) fn get_type_by_const(mut t: u32) -> crate::Result<String> {
8788
unsafe {
89+
t &= !(IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT);
8890
let s = zend_get_type_by_const(t as c_int);
8991
let mut s = CStr::from_ptr(s).to_str()?.to_string();
9092

0 commit comments

Comments
 (0)