• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

davidcole1340 / ext-php-rs / 16323306954

16 Jul 2025 03:10PM UTC coverage: 22.222% (+0.6%) from 21.654%
16323306954

Pull #482

github

web-flow
Merge de76d2402 into 1166e2910
Pull Request #482: feat(cargo-php)!: escalate privilege and to copy extension and edit ini file

0 of 48 new or added lines in 1 file covered. (0.0%)

193 existing lines in 10 files now uncovered.

870 of 3915 relevant lines covered (22.22%)

3.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.38
/src/flags.rs
1
//! Flags and enums used in PHP and the Zend engine.
2

3
use bitflags::bitflags;
4

5
#[cfg(not(php82))]
6
use crate::ffi::ZEND_ACC_REUSE_GET_ITERATOR;
7
use crate::ffi::{
8
    CONST_CS, CONST_DEPRECATED, CONST_NO_FILE_CACHE, CONST_PERSISTENT, E_COMPILE_ERROR,
9
    E_COMPILE_WARNING, E_CORE_ERROR, E_CORE_WARNING, E_DEPRECATED, E_ERROR, E_NOTICE, E_PARSE,
10
    E_RECOVERABLE_ERROR, E_STRICT, E_USER_DEPRECATED, E_USER_ERROR, E_USER_NOTICE, E_USER_WARNING,
11
    E_WARNING, IS_ARRAY, IS_CALLABLE, IS_CONSTANT_AST, IS_DOUBLE, IS_FALSE, IS_INDIRECT,
12
    IS_ITERABLE, IS_LONG, IS_MIXED, IS_NULL, IS_OBJECT, IS_PTR, IS_REFERENCE, IS_RESOURCE,
13
    IS_STRING, IS_TRUE, IS_TYPE_COLLECTABLE, IS_TYPE_REFCOUNTED, IS_UNDEF, IS_VOID, PHP_INI_ALL,
14
    PHP_INI_PERDIR, PHP_INI_SYSTEM, PHP_INI_USER, ZEND_ACC_ABSTRACT, ZEND_ACC_ANON_CLASS,
15
    ZEND_ACC_CALL_VIA_TRAMPOLINE, ZEND_ACC_CHANGED, ZEND_ACC_CLOSURE, ZEND_ACC_CONSTANTS_UPDATED,
16
    ZEND_ACC_CTOR, ZEND_ACC_DEPRECATED, ZEND_ACC_DONE_PASS_TWO, ZEND_ACC_EARLY_BINDING,
17
    ZEND_ACC_FAKE_CLOSURE, ZEND_ACC_FINAL, ZEND_ACC_GENERATOR, ZEND_ACC_HAS_FINALLY_BLOCK,
18
    ZEND_ACC_HAS_RETURN_TYPE, ZEND_ACC_HAS_TYPE_HINTS, ZEND_ACC_HEAP_RT_CACHE, ZEND_ACC_IMMUTABLE,
19
    ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, ZEND_ACC_INTERFACE, ZEND_ACC_LINKED, ZEND_ACC_NEARLY_LINKED,
20
    ZEND_ACC_NEVER_CACHE, ZEND_ACC_NO_DYNAMIC_PROPERTIES, ZEND_ACC_PRELOADED, ZEND_ACC_PRIVATE,
21
    ZEND_ACC_PROMOTED, ZEND_ACC_PROTECTED, ZEND_ACC_PUBLIC, ZEND_ACC_RESOLVED_INTERFACES,
22
    ZEND_ACC_RESOLVED_PARENT, ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES,
23
    ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT, ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE,
24
    ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS, ZEND_ACC_VARIADIC, ZEND_EVAL_CODE,
25
    ZEND_HAS_STATIC_IN_METHODS, ZEND_INTERNAL_FUNCTION, ZEND_USER_FUNCTION, Z_TYPE_FLAGS_SHIFT,
26
    _IS_BOOL,
27
};
28

29
use std::{convert::TryFrom, fmt::Display};
30

31
use crate::error::{Error, Result};
32

33
bitflags! {
34
    /// Flags used for setting the type of Zval.
35
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
36
    pub struct ZvalTypeFlags: u32 {
37
        /// Undefined
38
        const Undef = IS_UNDEF;
39
        /// Null
40
        const Null = IS_NULL;
41
        /// `false`
42
        const False = IS_FALSE;
43
        /// `true`
44
        const True = IS_TRUE;
45
        /// Integer
46
        const Long = IS_LONG;
47
        /// Floating point number
48
        const Double = IS_DOUBLE;
49
        /// String
50
        const String = IS_STRING;
51
        /// Array
52
        const Array = IS_ARRAY;
53
        /// Object
54
        const Object = IS_OBJECT;
55
        /// Resource
56
        const Resource = IS_RESOURCE;
57
        /// Reference
58
        const Reference = IS_REFERENCE;
59
        /// Callable
60
        const Callable = IS_CALLABLE;
61
        /// Constant expression
62
        const ConstantExpression = IS_CONSTANT_AST;
63
        /// Void
64
        const Void = IS_VOID;
65
        /// Pointer
66
        const Ptr = IS_PTR;
67
        /// Iterable
68
        const Iterable = IS_ITERABLE;
69

70
        /// Interned string extended
71
        const InternedStringEx = Self::String.bits();
72
        /// String extended
73
        const StringEx = Self::String.bits() | Self::RefCounted.bits();
74
        /// Array extended
75
        const ArrayEx = Self::Array.bits() | Self::RefCounted.bits() | Self::Collectable.bits();
76
        /// Object extended
77
        const ObjectEx = Self::Object.bits() | Self::RefCounted.bits() | Self::Collectable.bits();
78
        /// Resource extended
79
        const ResourceEx = Self::Resource.bits() | Self::RefCounted.bits();
80
        /// Reference extended
81
        const ReferenceEx = Self::Reference.bits() | Self::RefCounted.bits();
82
        /// Constant ast extended
83
        const ConstantAstEx = Self::ConstantExpression.bits() | Self::RefCounted.bits();
84

85
        /// Reference counted
86
        const RefCounted = (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT);
87
        /// Collectable
88
        const Collectable = (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT);
89
    }
90
}
91

92
bitflags! {
93
    /// Flags for building classes.
94
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
95
    pub struct ClassFlags: u32 {
96
        /// Final class or method
97
        const Final = ZEND_ACC_FINAL;
98
        /// Abstract method
99
        const Abstract = ZEND_ACC_ABSTRACT;
100
        /// Immutable `op_array` and class_entries
101
        /// (implemented only for lazy loading of `op_array`s)
102
        const Immutable = ZEND_ACC_IMMUTABLE;
103
        /// Function has typed arguments / class has typed props
104
        const HasTypeHints = ZEND_ACC_HAS_TYPE_HINTS;
105
        /// Top-level class or function declaration
106
        const TopLevel = ZEND_ACC_TOP_LEVEL;
107
        /// op_array or class is preloaded
108
        const Preloaded = ZEND_ACC_PRELOADED;
109

110
        /// Class entry is an interface
111
        const Interface = ZEND_ACC_INTERFACE;
112
        /// Class entry is a trait
113
        const Trait = ZEND_ACC_TRAIT;
114
        /// Anonymous class
115
        const AnonymousClass = ZEND_ACC_ANON_CLASS;
116
        /// Class linked with parent, interfaces and traits
117
        const Linked = ZEND_ACC_LINKED;
118
        /// Class is abstract, since it is set by any abstract method
119
        const ImplicitAbstractClass = ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
120
        /// Class has magic methods `__get`/`__set`/`__unset`/`__isset` that use guards
121
        const UseGuards = ZEND_ACC_USE_GUARDS;
122

123
        /// Class constants updated
124
        const ConstantsUpdated = ZEND_ACC_CONSTANTS_UPDATED;
125
        /// Objects of this class may not have dynamic properties
126
        const NoDynamicProperties = ZEND_ACC_NO_DYNAMIC_PROPERTIES;
127
        /// User class has methods with static variables
128
        const HasStaticInMethods = ZEND_HAS_STATIC_IN_METHODS;
129
        /// Children must reuse parent `get_iterator()`
130
        #[cfg(not(php82))]
131
        const ReuseGetIterator = ZEND_ACC_REUSE_GET_ITERATOR;
132
        /// Parent class is resolved (CE)
133
        const ResolvedParent = ZEND_ACC_RESOLVED_PARENT;
134
        /// Interfaces are resolved (CE)
135
        const ResolvedInterfaces = ZEND_ACC_RESOLVED_INTERFACES;
136
        /// Class has unresolved variance obligations
137
        const UnresolvedVariance = ZEND_ACC_UNRESOLVED_VARIANCE;
138
        /// Class is linked apart from variance obligations
139
        const NearlyLinked = ZEND_ACC_NEARLY_LINKED;
140

141
        /// Class cannot be serialized or unserialized
142
        #[cfg(php81)]
143
        const NotSerializable = crate::ffi::ZEND_ACC_NOT_SERIALIZABLE;
144
    }
145
}
146

147
bitflags! {
148
    /// Flags for building methods.
149
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
150
    pub struct MethodFlags: u32 {
151
        /// Visibility public
152
        const Public = ZEND_ACC_PUBLIC;
153
        /// Visibility protected
154
        const Protected = ZEND_ACC_PROTECTED;
155
        /// Visibility private
156
        const Private = ZEND_ACC_PRIVATE;
157
        /// Method or property overrides private one
158
        const Changed = ZEND_ACC_CHANGED;
159
        /// Static method
160
        const Static = ZEND_ACC_STATIC;
161
        /// Final method
162
        const Final = ZEND_ACC_FINAL;
163
        /// Abstract method
164
        const Abstract = ZEND_ACC_ABSTRACT;
165
        /// Immutable `op_array` and class_entries
166
        /// (implemented only for lazy loading of op_arrays)
167
        const Immutable = ZEND_ACC_IMMUTABLE;
168
        /// Function has typed arguments / class has typed props
169
        const HasTypeHints = ZEND_ACC_HAS_TYPE_HINTS;
170
        /// Top-level class or function declaration
171
        const TopLevel = ZEND_ACC_TOP_LEVEL;
172
        /// `op_array` or class is preloaded
173
        const Preloaded = ZEND_ACC_PRELOADED;
174

175
        /// Deprecation flag
176
        const Deprecated = ZEND_ACC_DEPRECATED;
177
        /// Function returning by reference
178
        const ReturnReference = ZEND_ACC_RETURN_REFERENCE;
179
        /// Function has a return type
180
        const HasReturnType = ZEND_ACC_HAS_RETURN_TYPE;
181
        /// Function with variable number of arguments
182
        const Variadic = ZEND_ACC_VARIADIC;
183
        /// `op_array` has finally blocks (user only)
184
        const HasFinallyBlock = ZEND_ACC_HAS_FINALLY_BLOCK;
185
        /// "main" `op_array` with `ZEND_DECLARE_CLASS_DELAYED` opcodes
186
        const EarlyBinding = ZEND_ACC_EARLY_BINDING;
187
        /// Closure uses `$this`
188
        const UsesThis = ZEND_ACC_USES_THIS;
189
        /// Call through user function trampoline
190
        ///
191
        /// # Example
192
        /// - `__call`
193
        /// - `__callStatic`
194
        const CallViaTrampoline = ZEND_ACC_CALL_VIA_TRAMPOLINE;
195
        /// Disable inline caching
196
        const NeverCache = ZEND_ACC_NEVER_CACHE;
197
        /// `op_array` is a clone of trait method
198
        const TraitClone = ZEND_ACC_TRAIT_CLONE;
199
        /// Function is a constructor
200
        const IsConstructor = ZEND_ACC_CTOR;
201
        /// Function is a closure
202
        const Closure = ZEND_ACC_CLOSURE;
203
        /// Function is a fake closure
204
        const FakeClosure = ZEND_ACC_FAKE_CLOSURE;
205
        /// Function is a generator
206
        const Generator = ZEND_ACC_GENERATOR;
207
        /// Function was processed by pass two (user only)
208
        const DonePassTwo = ZEND_ACC_DONE_PASS_TWO;
209
        /// `run_time_cache` allocated on heap (user only)
210
        const HeapRTCache = ZEND_ACC_HEAP_RT_CACHE;
211
        /// `op_array` uses strict mode types
212
        const StrictTypes = ZEND_ACC_STRICT_TYPES;
213
    }
214
}
215

216
bitflags! {
217
    /// Flags for building properties.
218
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
219
    pub struct PropertyFlags: u32 {
220
        /// Visibility public
221
        const Public = ZEND_ACC_PUBLIC;
222
        /// Visibility protected
223
        const Protected = ZEND_ACC_PROTECTED;
224
        /// Visibility private
225
        const Private = ZEND_ACC_PRIVATE;
226
        /// Property or method overrides private one
227
        const Changed = ZEND_ACC_CHANGED;
228
        /// Static property
229
        const Static = ZEND_ACC_STATIC;
230
        /// Promoted property
231
        const Promoted = ZEND_ACC_PROMOTED;
232
    }
233
}
234

235
bitflags! {
236
    /// Flags for building constants.
237
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
238
    pub struct ConstantFlags: u32 {
239
        /// Visibility public
240
        const Public = ZEND_ACC_PUBLIC;
241
        /// Visibility protected
242
        const Protected = ZEND_ACC_PROTECTED;
243
        /// Visibility private
244
        const Private = ZEND_ACC_PRIVATE;
245
        /// Promoted constant
246
        const Promoted = ZEND_ACC_PROMOTED;
247
    }
248
}
249

250
bitflags! {
251
    /// Flags for building module global constants.
252
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
253
    pub struct GlobalConstantFlags: u32 {
254
        /// No longer used -- always case-sensitive
255
        #[deprecated(note = "No longer used -- always case-sensitive")]
256
        const CaseSensitive = CONST_CS;
257
        /// Persistent
258
        const Persistent = CONST_PERSISTENT;
259
        /// Can't be saved in file cache
260
        const NoFileCache = CONST_NO_FILE_CACHE;
261
        /// Deprecated (this flag is not deprecated, it literally means the constant is deprecated)
262
        const Deprecated = CONST_DEPRECATED;
263
    }
264
}
265

266
bitflags! {
267
    /// Represents the result of a function.
268
    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
269
    pub struct ZendResult: i32 {
270
        /// Function call was successful.
271
        const Success = 0;
272
        /// Function call failed.
273
        const Failure = -1;
274
    }
275
}
276

277
bitflags! {
278
    /// Represents permissions for where a configuration setting may be set.
279
    pub struct IniEntryPermission: u32 {
280
        /// User
281
        const User = PHP_INI_USER;
282
        /// Per directory
283
        const PerDir = PHP_INI_PERDIR;
284
        /// System
285
        const System = PHP_INI_SYSTEM;
286
        /// All
287
        const All = PHP_INI_ALL;
288
    }
289
}
290

291
bitflags! {
292
    /// Represents error types when used via php_error_docref for example.
293
    pub struct ErrorType: u32 {
294
        /// Error
295
        const Error = E_ERROR;
296
        /// Warning
297
        const Warning = E_WARNING;
298
        /// Parse
299
        const Parse = E_PARSE;
300
        /// Notice
301
        const Notice = E_NOTICE;
302
        /// Core error
303
        const CoreError = E_CORE_ERROR;
304
        /// Core warning
305
        const CoreWarning = E_CORE_WARNING;
306
        /// Compile error
307
        const CompileError = E_COMPILE_ERROR;
308
        /// Compile warning
309
        const CompileWarning = E_COMPILE_WARNING;
310
        /// User error
311
        #[cfg_attr(php84, deprecated = "`E_USER_ERROR` is deprecated since PHP 8.4. Throw an exception instead.")]
312
        const UserError = E_USER_ERROR;
313
        /// User warning
314
        const UserWarning = E_USER_WARNING;
315
        /// User notice
316
        const UserNotice = E_USER_NOTICE;
317
        /// Strict
318
        const Strict = E_STRICT;
319
        /// Recoverable error
320
        const RecoverableError = E_RECOVERABLE_ERROR;
321
        /// Deprecated
322
        const Deprecated = E_DEPRECATED;
323
        /// User deprecated
324
        const UserDeprecated = E_USER_DEPRECATED;
325
    }
326
}
327

328
/// Represents the type of a function.
329
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
330
pub enum FunctionType {
331
    /// Internal function
332
    Internal,
333
    /// User function
334
    User,
335
    /// Eval code
336
    Eval,
337
}
338

339
impl From<u8> for FunctionType {
340
    #[allow(clippy::bad_bit_mask)]
341
    fn from(value: u8) -> Self {
×
342
        match value.into() {
×
343
            ZEND_INTERNAL_FUNCTION => Self::Internal,
×
344
            ZEND_USER_FUNCTION => Self::User,
×
345
            ZEND_EVAL_CODE => Self::Eval,
×
UNCOV
346
            _ => panic!("Unknown function type: {value}"),
×
347
        }
348
    }
349
}
350

351
/// Valid data types for PHP.
352
#[repr(C, u8)]
353
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
354
pub enum DataType {
355
    /// Undefined
356
    Undef,
357
    /// `null`
358
    Null,
359
    /// `false`
360
    False,
361
    /// `true`
362
    True,
363
    /// Integer (the irony)
364
    Long,
365
    /// Floating point number
366
    Double,
367
    /// String
368
    String,
369
    /// Array
370
    Array,
371
    /// Iterable
372
    Iterable,
373
    /// Object
374
    Object(Option<&'static str>),
375
    /// Resource
376
    Resource,
377
    /// Reference
378
    Reference,
379
    /// Callable
380
    Callable,
381
    /// Constant expression
382
    ConstantExpression,
383
    /// Void
384
    Void,
385
    /// Mixed
386
    Mixed,
387
    /// Boolean
388
    Bool,
389
    /// Pointer
390
    Ptr,
391
    /// Indirect (internal)
392
    Indirect,
393
}
394

395
impl Default for DataType {
396
    fn default() -> Self {
×
UNCOV
397
        Self::Void
×
398
    }
399
}
400

401
impl DataType {
402
    /// Returns the integer representation of the data type.
403
    #[must_use]
404
    pub const fn as_u32(&self) -> u32 {
40✔
405
        match self {
40✔
UNCOV
406
            DataType::Undef => IS_UNDEF,
×
407
            DataType::Null => IS_NULL,
32✔
408
            DataType::False => IS_FALSE,
×
UNCOV
409
            DataType::True => IS_TRUE,
×
410
            DataType::Long => IS_LONG,
2✔
UNCOV
411
            DataType::Double => IS_DOUBLE,
×
412
            DataType::String => IS_STRING,
4✔
413
            DataType::Array => IS_ARRAY,
×
414
            DataType::Object(_) => IS_OBJECT,
×
415
            DataType::Resource | DataType::Reference => IS_RESOURCE,
×
416
            DataType::Indirect => IS_INDIRECT,
×
417
            DataType::Callable => IS_CALLABLE,
×
418
            DataType::ConstantExpression => IS_CONSTANT_AST,
×
UNCOV
419
            DataType::Void => IS_VOID,
×
420
            DataType::Mixed => IS_MIXED,
2✔
421
            DataType::Bool => _IS_BOOL,
×
422
            DataType::Ptr => IS_PTR,
×
UNCOV
423
            DataType::Iterable => IS_ITERABLE,
×
424
        }
425
    }
426
}
427

428
// TODO: Ideally want something like this
429
// pub struct Type {
430
//     data_type: DataType,
431
//     is_refcounted: bool,
432
//     is_collectable: bool,
433
//     is_immutable: bool,
434
//     is_persistent: bool,
435
// }
436
//
437
// impl From<u32> for Type { ... }
438

439
impl TryFrom<ZvalTypeFlags> for DataType {
440
    type Error = Error;
441

UNCOV
442
    fn try_from(value: ZvalTypeFlags) -> Result<Self> {
×
443
        macro_rules! contains {
444
            ($t: ident) => {
445
                if value.contains(ZvalTypeFlags::$t) {
446
                    return Ok(DataType::$t);
447
                }
448
            };
449
        }
450

451
        contains!(Undef);
×
452
        contains!(Null);
×
453
        contains!(False);
×
454
        contains!(True);
×
455
        contains!(False);
×
456
        contains!(Long);
×
457
        contains!(Double);
×
458
        contains!(String);
×
459
        contains!(Array);
×
460
        contains!(Resource);
×
461
        contains!(Callable);
×
462
        contains!(ConstantExpression);
×
UNCOV
463
        contains!(Void);
×
464

465
        if value.contains(ZvalTypeFlags::Object) {
×
UNCOV
466
            return Ok(DataType::Object(None));
×
467
        }
468

UNCOV
469
        Err(Error::UnknownDatatype(0))
×
470
    }
471
}
472

473
impl From<u32> for DataType {
474
    #[allow(clippy::bad_bit_mask)]
475
    fn from(value: u32) -> Self {
94✔
476
        macro_rules! contains {
477
            ($c: ident, $t: ident) => {
478
                if (value & $c) == $c {
479
                    return DataType::$t;
480
                }
481
            };
482
        }
483

484
        contains!(IS_VOID, Void);
94✔
485
        contains!(IS_PTR, Ptr);
93✔
486
        contains!(IS_INDIRECT, Indirect);
92✔
487
        contains!(IS_CALLABLE, Callable);
91✔
488
        contains!(IS_CONSTANT_AST, ConstantExpression);
91✔
489
        contains!(IS_REFERENCE, Reference);
89✔
490
        contains!(IS_RESOURCE, Resource);
87✔
491
        contains!(IS_ARRAY, Array);
85✔
492
        contains!(IS_STRING, String);
83✔
493
        contains!(IS_DOUBLE, Double);
53✔
494
        contains!(IS_LONG, Long);
52✔
495
        contains!(IS_TRUE, True);
22✔
496
        contains!(IS_FALSE, False);
21✔
497
        contains!(IS_NULL, Null);
20✔
498

499
        if (value & IS_OBJECT) == IS_OBJECT {
19✔
500
            return DataType::Object(None);
16✔
501
        }
502

503
        contains!(IS_UNDEF, Undef);
504

UNCOV
505
        DataType::Mixed
×
506
    }
507
}
508

509
impl Display for DataType {
510
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
×
511
        match self {
×
512
            DataType::Undef => write!(f, "Undefined"),
×
513
            DataType::Null => write!(f, "Null"),
×
514
            DataType::False => write!(f, "False"),
×
515
            DataType::True => write!(f, "True"),
×
516
            DataType::Long => write!(f, "Long"),
×
517
            DataType::Double => write!(f, "Double"),
×
518
            DataType::String => write!(f, "String"),
×
519
            DataType::Array => write!(f, "Array"),
×
520
            DataType::Object(obj) => write!(f, "{}", obj.as_deref().unwrap_or("Object")),
×
521
            DataType::Resource => write!(f, "Resource"),
×
522
            DataType::Reference => write!(f, "Reference"),
×
523
            DataType::Callable => write!(f, "Callable"),
×
524
            DataType::ConstantExpression => write!(f, "Constant Expression"),
×
525
            DataType::Void => write!(f, "Void"),
×
526
            DataType::Bool => write!(f, "Bool"),
×
527
            DataType::Mixed => write!(f, "Mixed"),
×
528
            DataType::Ptr => write!(f, "Pointer"),
×
529
            DataType::Indirect => write!(f, "Indirect"),
×
UNCOV
530
            DataType::Iterable => write!(f, "Iterable"),
×
531
        }
532
    }
533
}
534

535
#[cfg(test)]
536
mod tests {
537
    #![allow(clippy::unnecessary_fallible_conversions)]
538
    use super::DataType;
539
    use crate::ffi::{
540
        IS_ARRAY, IS_ARRAY_EX, IS_CONSTANT_AST, IS_CONSTANT_AST_EX, IS_DOUBLE, IS_FALSE,
541
        IS_INDIRECT, IS_INTERNED_STRING_EX, IS_LONG, IS_NULL, IS_OBJECT, IS_OBJECT_EX, IS_PTR,
542
        IS_REFERENCE, IS_REFERENCE_EX, IS_RESOURCE, IS_RESOURCE_EX, IS_STRING, IS_STRING_EX,
543
        IS_TRUE, IS_UNDEF, IS_VOID,
544
    };
545
    use std::convert::TryFrom;
546

547
    #[test]
548
    fn test_datatype() {
549
        macro_rules! test {
550
            ($c: ident, $t: ident) => {
551
                assert_eq!(DataType::try_from($c), Ok(DataType::$t));
552
            };
553
        }
554

555
        test!(IS_UNDEF, Undef);
556
        test!(IS_NULL, Null);
557
        test!(IS_FALSE, False);
558
        test!(IS_TRUE, True);
559
        test!(IS_LONG, Long);
560
        test!(IS_DOUBLE, Double);
561
        test!(IS_STRING, String);
562
        test!(IS_ARRAY, Array);
563
        assert_eq!(DataType::try_from(IS_OBJECT), Ok(DataType::Object(None)));
564
        test!(IS_RESOURCE, Resource);
565
        test!(IS_REFERENCE, Reference);
566
        test!(IS_CONSTANT_AST, ConstantExpression);
567
        test!(IS_INDIRECT, Indirect);
568
        test!(IS_VOID, Void);
569
        test!(IS_PTR, Ptr);
570

571
        test!(IS_INTERNED_STRING_EX, String);
572
        test!(IS_STRING_EX, String);
573
        test!(IS_ARRAY_EX, Array);
574
        assert_eq!(DataType::try_from(IS_OBJECT_EX), Ok(DataType::Object(None)));
575
        test!(IS_RESOURCE_EX, Resource);
576
        test!(IS_REFERENCE_EX, Reference);
577
        test!(IS_CONSTANT_AST_EX, ConstantExpression);
578
    }
579
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc