1use crate::sys::*;
14use derive_more::From;
15use std::{
16 ffi::CStr,
17 fmt::{self, Debug, Display},
18 os::raw::c_int,
19};
20
21#[derive(Clone, Copy, PartialEq, Eq)]
23pub struct TypeInfo {
24 t: u32,
25}
26
27impl TypeInfo {
28 pub const ARRAY: TypeInfo = TypeInfo::from_raw(IS_ARRAY);
30 pub const BOOL: TypeInfo = TypeInfo::from_raw(_IS_BOOL);
32 pub const DOUBLE: TypeInfo = TypeInfo::from_raw(IS_DOUBLE);
34 pub const LONG: TypeInfo = TypeInfo::from_raw(IS_LONG);
36 pub const NULL: TypeInfo = TypeInfo::from_raw(IS_NULL);
38 pub const OBJECT: TypeInfo = TypeInfo::from_raw(IS_OBJECT);
40 pub const REFERENCE: TypeInfo = TypeInfo::from_raw(IS_REFERENCE);
42 pub const RESOURCE: TypeInfo = TypeInfo::from_raw(IS_RESOURCE);
44 pub const STRING: TypeInfo = TypeInfo::from_raw(IS_STRING);
46 pub const UNDEF: TypeInfo = TypeInfo::from_raw(IS_UNDEF);
48}
49
50impl TypeInfo {
51 pub const fn from_raw(t: u32) -> Self {
53 Self { t }
54 }
55
56 pub const fn into_raw(self) -> u32 {
58 self.t
59 }
60
61 pub const fn is_undef(self) -> bool {
63 self.t == IS_UNDEF
64 }
65
66 pub const fn is_null(self) -> bool {
68 self.t == IS_NULL
69 }
70
71 pub const fn is_bool(self) -> bool {
73 self.is_true() || self.is_false()
74 }
75
76 pub const fn is_true(self) -> bool {
78 get_base_type_by_raw(self.t) == IS_TRUE
79 }
80
81 pub const fn is_false(self) -> bool {
83 get_base_type_by_raw(self.t) == IS_FALSE
84 }
85
86 pub const fn is_long(self) -> bool {
88 get_base_type_by_raw(self.t) == IS_LONG
89 }
90
91 pub const fn is_double(self) -> bool {
93 get_base_type_by_raw(self.t) == IS_DOUBLE
94 }
95
96 pub const fn is_string(self) -> bool {
98 get_base_type_by_raw(self.t) == IS_STRING
99 }
100
101 pub const fn is_array(self) -> bool {
103 get_base_type_by_raw(self.t) == IS_ARRAY
104 }
105
106 pub const fn is_object(self) -> bool {
108 get_base_type_by_raw(self.t) == IS_OBJECT
109 }
110
111 pub const fn is_resource(self) -> bool {
113 get_base_type_by_raw(self.t) == IS_RESOURCE
114 }
115
116 pub const fn is_reference(self) -> bool {
118 get_base_type_by_raw(self.t) == IS_REFERENCE
119 }
120
121 pub const fn get_base_type(self) -> TypeInfo {
123 Self::from_raw(get_base_type_by_raw(self.t))
124 }
125
126 #[inline]
131 pub fn get_base_type_name(self) -> &'static CStr {
132 unsafe {
133 let t = get_base_type_by_raw(self.t);
134
135 if t == IS_UNDEF {
136 return c"undef";
137 }
138 if t == IS_REFERENCE {
139 return c"reference";
140 }
141
142 let s = zend_get_type_by_const(t as c_int);
143 let s = CStr::from_ptr(s);
144
145 let bs = s.to_bytes();
147 if bs == b"boolean" {
148 return c"bool";
149 }
150 if bs == b"integer" {
151 return c"int";
152 }
153
154 s
155 }
156 }
157}
158
159impl Debug for TypeInfo {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 f.debug_struct("TypeInfo")
162 .field("base_name", &self.get_base_type_name())
163 .field("base", &self.get_base_type().t)
164 .field("raw", &self.t)
165 .finish()
166 }
167}
168
169impl From<u32> for TypeInfo {
170 fn from(n: u32) -> Self {
171 Self::from_raw(n)
172 }
173}
174
175impl Display for TypeInfo {
176 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177 let t = self.get_base_type_name().to_str().unwrap_or("unknown");
178 Display::fmt(t, f)
179 }
180}
181
182const fn get_base_type_by_raw(t: u32) -> u32 {
183 t & !(!0 << Z_TYPE_FLAGS_SHIFT)
184}
185
186#[derive(From)]
188pub enum Scalar {
189 Null,
191 Bool(bool),
193 I64(i64),
195 F64(f64),
197 String(String),
199 Bytes(Vec<u8>),
201}
202
203impl From<()> for Scalar {
204 fn from(_: ()) -> Self {
205 Self::Null
206 }
207}
208
209impl From<&str> for Scalar {
210 fn from(s: &str) -> Self {
211 Self::String(s.to_owned())
212 }
213}
214
215impl From<&[u8]> for Scalar {
216 fn from(b: &[u8]) -> Self {
217 Self::Bytes(b.to_owned())
218 }
219}
220
221#[derive(Debug, Clone, PartialEq, Eq)]
223pub enum ArgumentTypeHint {
224 Null,
226 Bool,
228 Int,
230 Float,
232 String,
234 Array,
236 Object,
238 Callable,
240 Iterable,
242 Mixed,
244 ClassEntry(String),
246}
247
248#[derive(Debug, Clone, PartialEq, Eq)]
250pub enum ReturnTypeHint {
251 Null,
253 Bool,
255 Int,
257 Float,
259 String,
261 Array,
263 Object,
265 Callable,
267 Iterable,
269 Mixed,
271 ClassEntry(String),
273 Never,
275 Void,
277}