@@ -12,7 +12,7 @@ use crate::{
1212} ;
1313
1414/// Valid data types for PHP.
15- #[ derive( Clone , Copy , Debug ) ]
15+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
1616#[ repr( u32 ) ]
1717pub enum DataType {
1818 Undef = IS_UNDEF ,
@@ -33,6 +33,17 @@ pub enum DataType {
3333 Void = IS_VOID ,
3434}
3535
36+ // TODO: Ideally want something like this
37+ // pub struct Type {
38+ // data_type: DataType,
39+ // is_refcounted: bool,
40+ // is_collectable: bool,
41+ // is_immutable: bool,
42+ // is_persistent: bool,
43+ // }
44+ //
45+ // impl From<u32> for Type { ... }
46+
3647impl TryFrom < ZvalTypeFlags > for DataType {
3748 type Error = Error ;
3849
@@ -64,12 +75,37 @@ impl TryFrom<ZvalTypeFlags> for DataType {
6475 }
6576}
6677
67- impl TryFrom < u8 > for DataType {
78+ impl TryFrom < u32 > for DataType {
6879 type Error = Error ;
6980
70- fn try_from ( value : u8 ) -> Result < Self > {
71- let flags = ZvalTypeFlags :: from_bits ( value. into ( ) ) . ok_or ( Error :: UnknownDatatype ( value) ) ?;
72- DataType :: try_from ( flags)
81+ #[ allow( clippy:: bad_bit_mask) ]
82+ fn try_from ( value : u32 ) -> Result < Self > {
83+ macro_rules! contains {
84+ ( $c: ident, $t: ident) => {
85+ if ( value & $c) == $c {
86+ return Ok ( DataType :: $t) ;
87+ }
88+ } ;
89+ }
90+
91+ contains ! ( IS_VOID , Void ) ;
92+ contains ! ( IS_CALLABLE , Callable ) ;
93+ contains ! ( IS_CONSTANT_AST , ConstantExpression ) ;
94+ contains ! ( IS_CONSTANT_AST , ConstantExpression ) ;
95+ contains ! ( IS_CONSTANT_AST , ConstantExpression ) ;
96+ contains ! ( IS_REFERENCE , Reference ) ;
97+ contains ! ( IS_RESOURCE , Resource ) ;
98+ contains ! ( IS_OBJECT , Object ) ;
99+ contains ! ( IS_ARRAY , Array ) ;
100+ contains ! ( IS_STRING , String ) ;
101+ contains ! ( IS_DOUBLE , Double ) ;
102+ contains ! ( IS_LONG , Long ) ;
103+ contains ! ( IS_TRUE , True ) ;
104+ contains ! ( IS_FALSE , False ) ;
105+ contains ! ( IS_NULL , Null ) ;
106+ contains ! ( IS_UNDEF , Undef ) ;
107+
108+ Err ( Error :: UnknownDatatype ( value) )
73109 }
74110}
75111
@@ -93,3 +129,47 @@ impl Display for DataType {
93129 }
94130 }
95131}
132+
133+ #[ cfg( test) ]
134+ mod tests {
135+ use super :: DataType ;
136+ use crate :: bindings:: {
137+ IS_ARRAY , IS_ARRAY_EX , IS_CALLABLE , IS_CONSTANT_AST , IS_CONSTANT_AST_EX , IS_DOUBLE ,
138+ IS_FALSE , IS_INTERNED_STRING_EX , IS_LONG , IS_NULL , IS_OBJECT , IS_OBJECT_EX , IS_REFERENCE ,
139+ IS_REFERENCE_EX , IS_RESOURCE , IS_RESOURCE_EX , IS_STRING , IS_STRING_EX , IS_TRUE , IS_UNDEF ,
140+ IS_VOID ,
141+ } ;
142+ use std:: convert:: TryFrom ;
143+
144+ #[ test]
145+ fn test_datatype ( ) {
146+ macro_rules! test {
147+ ( $c: ident, $t: ident) => {
148+ assert_eq!( DataType :: try_from( $c) , Ok ( DataType :: $t) ) ;
149+ } ;
150+ }
151+
152+ test ! ( IS_UNDEF , Undef ) ;
153+ test ! ( IS_NULL , Null ) ;
154+ test ! ( IS_FALSE , False ) ;
155+ test ! ( IS_TRUE , True ) ;
156+ test ! ( IS_LONG , Long ) ;
157+ test ! ( IS_DOUBLE , Double ) ;
158+ test ! ( IS_STRING , String ) ;
159+ test ! ( IS_ARRAY , Array ) ;
160+ test ! ( IS_OBJECT , Object ) ;
161+ test ! ( IS_RESOURCE , Resource ) ;
162+ test ! ( IS_REFERENCE , Reference ) ;
163+ test ! ( IS_CONSTANT_AST , ConstantExpression ) ;
164+ test ! ( IS_CALLABLE , Callable ) ;
165+ test ! ( IS_VOID , Void ) ;
166+
167+ test ! ( IS_INTERNED_STRING_EX , String ) ;
168+ test ! ( IS_STRING_EX , String ) ;
169+ test ! ( IS_ARRAY_EX , Array ) ;
170+ test ! ( IS_OBJECT_EX , Object ) ;
171+ test ! ( IS_RESOURCE_EX , Resource ) ;
172+ test ! ( IS_REFERENCE_EX , Reference ) ;
173+ test ! ( IS_CONSTANT_AST_EX , ConstantExpression ) ;
174+ }
175+ }
0 commit comments