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

extphprs / ext-php-rs / 25379163335

05 May 2026 01:25PM UTC coverage: 72.479% (+6.2%) from 66.241%
25379163335

Pull #734

github

web-flow
Merge 889e3cde4 into 0912e7c24
Pull Request #734: feat!: PHP 8 union, intersection, DNF, and class-union type hints

2871 of 3074 new or added lines in 21 files covered. (93.4%)

3 existing lines in 2 files now uncovered.

11514 of 15886 relevant lines covered (72.48%)

33.34 hits per line

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

72.63
/crates/types/src/data_type.rs
1
//! [`DataType`] — the value-side enum the parser produces for primitive type
2
//! names. Lives here, not in the runtime crate, because [`crate::PhpType`]
3
//! carries it and the parser must construct it.
4
//!
5
//! The runtime crate hangs FFI conversion helpers off this enum (e.g.
6
//! `ext_php_rs::flags::data_type_from_raw`); those depend on PHP's
7
//! `IS_*` constants and stay there.
8

9
use std::fmt::{self, Display};
10

11
/// Valid data types for a [`Zval`](https://docs.rs/ext-php-rs/latest/ext_php_rs/types/struct.Zval.html).
12
#[repr(C, u8)]
13
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
14
pub enum DataType {
15
    /// Undefined
16
    Undef,
17
    /// `null`
18
    Null,
19
    /// `false`
20
    False,
21
    /// `true`
22
    True,
23
    /// Integer (the irony)
24
    Long,
25
    /// Floating point number
26
    Double,
27
    /// String
28
    String,
29
    /// Array
30
    Array,
31
    /// Iterable
32
    Iterable,
33
    /// Object
34
    Object(Option<&'static str>),
35
    /// Resource
36
    Resource,
37
    /// Reference
38
    Reference,
39
    /// Callable
40
    Callable,
41
    /// Constant expression
42
    ConstantExpression,
43
    /// Void
44
    #[default]
45
    Void,
46
    /// Mixed
47
    Mixed,
48
    /// Boolean
49
    Bool,
50
    /// Pointer
51
    Ptr,
52
    /// Indirect (internal)
53
    Indirect,
54
}
55

56
impl Display for DataType {
57
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3✔
58
        match self {
3✔
NEW
59
            DataType::Undef => write!(f, "Undefined"),
×
NEW
60
            DataType::Null => write!(f, "Null"),
×
NEW
61
            DataType::False => write!(f, "False"),
×
NEW
62
            DataType::True => write!(f, "True"),
×
63
            DataType::Long => write!(f, "Long"),
3✔
NEW
64
            DataType::Double => write!(f, "Double"),
×
NEW
65
            DataType::String => write!(f, "String"),
×
NEW
66
            DataType::Array => write!(f, "Array"),
×
NEW
67
            DataType::Object(obj) => write!(f, "{}", obj.as_deref().unwrap_or("Object")),
×
NEW
68
            DataType::Resource => write!(f, "Resource"),
×
NEW
69
            DataType::Reference => write!(f, "Reference"),
×
NEW
70
            DataType::Callable => write!(f, "Callable"),
×
NEW
71
            DataType::ConstantExpression => write!(f, "Constant Expression"),
×
NEW
72
            DataType::Void => write!(f, "Void"),
×
NEW
73
            DataType::Bool => write!(f, "Bool"),
×
NEW
74
            DataType::Mixed => write!(f, "Mixed"),
×
NEW
75
            DataType::Ptr => write!(f, "Pointer"),
×
NEW
76
            DataType::Indirect => write!(f, "Indirect"),
×
NEW
77
            DataType::Iterable => write!(f, "Iterable"),
×
78
        }
79
    }
3✔
80
}
81

82
#[cfg(feature = "proc-macro")]
83
impl quote::ToTokens for DataType {
84
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
42✔
85
        use quote::quote;
86
        let stream = match self {
42✔
NEW
87
            DataType::Undef => quote!(::ext_php_rs::flags::DataType::Undef),
×
88
            DataType::Null => quote!(::ext_php_rs::flags::DataType::Null),
5✔
NEW
89
            DataType::False => quote!(::ext_php_rs::flags::DataType::False),
×
90
            DataType::True => quote!(::ext_php_rs::flags::DataType::True),
1✔
91
            DataType::Long => quote!(::ext_php_rs::flags::DataType::Long),
14✔
92
            DataType::Double => quote!(::ext_php_rs::flags::DataType::Double),
1✔
93
            DataType::String => quote!(::ext_php_rs::flags::DataType::String),
13✔
NEW
94
            DataType::Array => quote!(::ext_php_rs::flags::DataType::Array),
×
95
            DataType::Iterable => quote!(::ext_php_rs::flags::DataType::Iterable),
1✔
96
            DataType::Object(None) => {
97
                quote!(::ext_php_rs::flags::DataType::Object(
2✔
98
                    ::core::option::Option::None
99
                ))
100
            }
101
            DataType::Object(Some(name)) => {
1✔
102
                quote!(
1✔
103
                    ::ext_php_rs::flags::DataType::Object(
104
                        ::core::option::Option::Some(#name)
105
                    )
106
                )
107
            }
NEW
108
            DataType::Resource => quote!(::ext_php_rs::flags::DataType::Resource),
×
NEW
109
            DataType::Reference => quote!(::ext_php_rs::flags::DataType::Reference),
×
110
            DataType::Callable => quote!(::ext_php_rs::flags::DataType::Callable),
1✔
111
            DataType::ConstantExpression => {
NEW
112
                quote!(::ext_php_rs::flags::DataType::ConstantExpression)
×
113
            }
114
            DataType::Void => quote!(::ext_php_rs::flags::DataType::Void),
1✔
115
            DataType::Mixed => quote!(::ext_php_rs::flags::DataType::Mixed),
1✔
116
            DataType::Bool => quote!(::ext_php_rs::flags::DataType::Bool),
1✔
NEW
117
            DataType::Ptr => quote!(::ext_php_rs::flags::DataType::Ptr),
×
NEW
118
            DataType::Indirect => quote!(::ext_php_rs::flags::DataType::Indirect),
×
119
        };
120
        stream.to_tokens(tokens);
42✔
121
    }
42✔
122
}
123

124
#[cfg(all(test, feature = "proc-macro"))]
125
mod tokens_tests {
126
    use super::DataType;
127
    use quote::quote;
128

129
    fn render<T: quote::ToTokens>(value: &T) -> String {
12✔
130
        quote!(#value).to_string()
12✔
131
    }
12✔
132

133
    #[test]
134
    fn each_primitive_emits_the_runtime_path() {
1✔
135
        let cases: &[(DataType, proc_macro2::TokenStream)] = &[
1✔
136
            (DataType::Long, quote!(::ext_php_rs::flags::DataType::Long)),
1✔
137
            (DataType::Null, quote!(::ext_php_rs::flags::DataType::Null)),
1✔
138
            (
1✔
139
                DataType::String,
1✔
140
                quote!(::ext_php_rs::flags::DataType::String),
1✔
141
            ),
1✔
142
            (DataType::Bool, quote!(::ext_php_rs::flags::DataType::Bool)),
1✔
143
            (DataType::True, quote!(::ext_php_rs::flags::DataType::True)),
1✔
144
            (
1✔
145
                DataType::Double,
1✔
146
                quote!(::ext_php_rs::flags::DataType::Double),
1✔
147
            ),
1✔
148
            (DataType::Void, quote!(::ext_php_rs::flags::DataType::Void)),
1✔
149
            (
1✔
150
                DataType::Mixed,
1✔
151
                quote!(::ext_php_rs::flags::DataType::Mixed),
1✔
152
            ),
1✔
153
            (
1✔
154
                DataType::Iterable,
1✔
155
                quote!(::ext_php_rs::flags::DataType::Iterable),
1✔
156
            ),
1✔
157
            (
1✔
158
                DataType::Callable,
1✔
159
                quote!(::ext_php_rs::flags::DataType::Callable),
1✔
160
            ),
1✔
161
        ];
1✔
162
        for (dt, expected) in cases {
10✔
163
            assert_eq!(render(dt), expected.to_string(), "DataType::{dt:?}");
10✔
164
        }
165
    }
1✔
166

167
    #[test]
168
    fn object_none_emits_explicit_option_none() {
1✔
169
        let dt = DataType::Object(None);
1✔
170
        assert_eq!(
1✔
171
            render(&dt),
1✔
172
            quote!(::ext_php_rs::flags::DataType::Object(
1✔
173
                ::core::option::Option::None
174
            ))
175
            .to_string()
1✔
176
        );
177
    }
1✔
178

179
    #[test]
180
    fn object_some_inlines_static_name() {
1✔
181
        let dt = DataType::Object(Some("Foo"));
1✔
182
        assert_eq!(
1✔
183
            render(&dt),
1✔
184
            quote!(::ext_php_rs::flags::DataType::Object(
1✔
185
                ::core::option::Option::Some("Foo")
186
            ))
187
            .to_string()
1✔
188
        );
189
    }
1✔
190
}
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

© 2026 Coveralls, Inc