Skip to content

Commit cfcbebd

Browse files
committed
Add enum Type.
1 parent 6352e0c commit cfcbebd

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

phper/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ keywords = ["php", "binding", "extension"]
1515
[dependencies]
1616
anyhow = "1.0.40"
1717
clap = "3.0.0-beta.2"
18+
num-derive = "0.3"
19+
num-traits = "0.2"
1820
once_cell = "1.7.2"
1921
phper-alloc = { version = "0.2.0-alpha.2", path = "../phper-alloc" }
2022
phper-macros = { version = "0.2.0-alpha.2", path = "../phper-macros" }

phper/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ See [examples](https://github.com/jmjoy/phper/tree/master/examples).
122122
[Unlicense](https://github.com/jmjoy/phper/blob/master/LICENSE).
123123
*/
124124

125+
#[macro_use]
126+
extern crate num_derive;
127+
125128
#[macro_use]
126129
mod macros;
127130

phper/src/types.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
use crate::sys::*;
2-
use std::{ffi::CStr, os::raw::c_int};
2+
use num_traits::cast::FromPrimitive;
3+
use std::{convert::TryInto, ffi::CStr, os::raw::c_int};
4+
5+
#[derive(FromPrimitive, PartialEq)]
6+
#[repr(u32)]
7+
#[non_exhaustive]
8+
pub enum Type {
9+
Undef = IS_UNDEF,
10+
Null = IS_NULL,
11+
False = IS_FALSE,
12+
True = IS_TRUE,
13+
Long = IS_LONG,
14+
Double = IS_DOUBLE,
15+
String = IS_STRING,
16+
Array = IS_ARRAY,
17+
Object = IS_OBJECT,
18+
Resource = IS_RESOURCE,
19+
Reference = IS_REFERENCE,
20+
ConstantAst = IS_CONSTANT_AST,
21+
IsCallable = IS_CALLABLE,
22+
}
23+
24+
impl From<u32> for Type {
25+
fn from(n: u32) -> Self {
26+
match FromPrimitive::from_u32(n) {
27+
Some(t) => t,
28+
None => unreachable!("Type is not exhaustive, should contains: {}", n),
29+
}
30+
}
31+
}
332

433
pub(crate) fn get_type_by_const(t: u32) -> crate::Result<String> {
534
unsafe {

phper/src/values.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use crate::{
2-
arrays::Array, errors::Throwable, sys::*, types::get_type_by_const,
3-
utils::ensure_end_with_zero, TypeError,
2+
arrays::Array,
3+
errors::Throwable,
4+
sys::*,
5+
types::{get_type_by_const, Type},
6+
utils::ensure_end_with_zero,
7+
TypeError,
48
};
59
use std::{
610
mem::zeroed,
@@ -119,28 +123,31 @@ impl Val {
119123
}
120124

121125
#[inline]
122-
fn type_info(&self) -> u32 {
123-
unsafe { self.inner.u1.type_info }
126+
fn get_type(&self) -> Type {
127+
let t = unsafe { self.inner.u1.type_info };
128+
t.into()
124129
}
125130

126-
fn type_name(&self) -> crate::Result<String> {
127-
get_type_by_const(unsafe { self.type_info() })
131+
fn get_type_name(&self) -> crate::Result<String> {
132+
get_type_by_const(unsafe { self.get_type() as u32 })
128133
}
129134

130-
unsafe fn type_info_mut(&mut self) -> &mut u32 {
131-
&mut self.inner.u1.type_info
135+
fn set_type(&mut self, t: Type) {
136+
unsafe {
137+
self.inner.u1.type_info = t as u32;
138+
}
132139
}
133140

134141
pub fn as_bool(&self) -> crate::Result<bool> {
135-
match self.type_info() {
136-
IS_TRUE => Ok(true),
137-
IS_FALSE => Ok(false),
142+
match self.get_type() {
143+
Type::True => Ok(true),
144+
Type::False => Ok(false),
138145
_ => Err(self.must_be_type_error("bool").into()),
139146
}
140147
}
141148

142149
pub fn as_i64(&self) -> crate::Result<i64> {
143-
if self.type_info() == IS_LONG {
150+
if self.get_type() == Type::Long {
144151
unsafe { Ok(self.inner.value.lval) }
145152
} else {
146153
Err(self.must_be_type_error("long").into())
@@ -152,15 +159,15 @@ impl Val {
152159
}
153160

154161
pub fn as_f64(&self) -> crate::Result<f64> {
155-
if self.type_info() == IS_DOUBLE {
162+
if self.get_type() == Type::Double {
156163
unsafe { Ok(self.inner.value.dval) }
157164
} else {
158165
Err(self.must_be_type_error("float").into())
159166
}
160167
}
161168

162169
pub fn as_string(&self) -> crate::Result<String> {
163-
if self.type_info() == IS_STRING {
170+
if self.get_type() == Type::String {
164171
unsafe {
165172
let s = self.inner.value.str;
166173
let buf = from_raw_parts(&(*s).val as *const c_char as *const u8, (*s).len);
@@ -185,7 +192,7 @@ impl Val {
185192
pub fn as_array(&self) {}
186193

187194
fn must_be_type_error(&self, expect_type: &str) -> crate::Error {
188-
match self.type_name() {
195+
match self.get_type_name() {
189196
Ok(type_name) => {
190197
let message = format!("must be of type {}, {} given", expect_type, type_name);
191198
TypeError::new(message).into()
@@ -201,17 +208,13 @@ pub trait SetVal {
201208

202209
impl SetVal for () {
203210
fn set_val(self, val: &mut Val) {
204-
unsafe {
205-
*val.type_info_mut() = IS_NULL;
206-
}
211+
val.set_type(Type::Null);
207212
}
208213
}
209214

210215
impl SetVal for bool {
211216
fn set_val(self, val: &mut Val) {
212-
unsafe {
213-
*val.type_info_mut() = if self { IS_TRUE } else { IS_FALSE };
214-
}
217+
val.set_type(if self { Type::True } else { Type::False });
215218
}
216219
}
217220

@@ -229,18 +232,18 @@ impl SetVal for u32 {
229232

230233
impl SetVal for i64 {
231234
fn set_val(self, val: &mut Val) {
235+
val.set_type(Type::Long);
232236
unsafe {
233237
(*val.as_mut_ptr()).value.lval = self;
234-
(*val.as_mut_ptr()).u1.type_info = IS_LONG;
235238
}
236239
}
237240
}
238241

239242
impl SetVal for f64 {
240243
fn set_val(self, val: &mut Val) {
244+
val.set_type(Type::Double);
241245
unsafe {
242246
(*val.as_mut_ptr()).value.dval = self;
243-
(*val.as_mut_ptr()).u1.type_info = IS_DOUBLE;
244247
}
245248
}
246249
}

0 commit comments

Comments
 (0)