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

davidcole1340 / ext-php-rs / 15997940746

01 Jul 2025 11:24AM UTC coverage: 20.518% (-0.03%) from 20.545%
15997940746

Pull #457

github

web-flow
Merge ee1c5bf3e into 3dd870ae9
Pull Request #457: fix(FunctionBuilder): return type '?void' is now just 'void'

1 of 1 new or added line in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

760 of 3704 relevant lines covered (20.52%)

3.56 hits per line

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

69.23
/src/zend/_type.rs
1
use std::{ffi::c_void, ptr};
2

3
use crate::{
4
    ffi::{
5
        zend_type, IS_MIXED, MAY_BE_ANY, MAY_BE_BOOL, _IS_BOOL, _ZEND_IS_VARIADIC_BIT,
6
        _ZEND_SEND_MODE_SHIFT, _ZEND_TYPE_NULLABLE_BIT,
7
    },
8
    flags::DataType,
9
};
10

11
/// Internal Zend type.
12
pub type ZendType = zend_type;
13

14
impl ZendType {
15
    /// Builds an empty Zend type container.
16
    ///
17
    /// # Parameters
18
    ///
19
    /// * `pass_by_ref` - Whether the value should be passed by reference.
20
    /// * `is_variadic` - Whether this type represents a variadic argument.
21
    #[must_use]
22
    pub fn empty(pass_by_ref: bool, is_variadic: bool) -> Self {
1✔
23
        Self {
24
            ptr: ptr::null_mut::<c_void>(),
2✔
25
            type_mask: Self::arg_info_flags(pass_by_ref, is_variadic),
2✔
26
        }
27
    }
28

29
    /// Attempts to create a zend type for a given datatype. Returns an option
30
    /// containing the type.
31
    ///
32
    /// Returns [`None`] if the data type was a class object where the class
33
    /// name could not be converted into a C string (i.e. contained
34
    /// NUL-bytes).
35
    ///
36
    /// # Parameters
37
    ///
38
    /// * `type_` - Data type to create zend type for.
39
    /// * `pass_by_ref` - Whether the type should be passed by reference.
40
    /// * `is_variadic` - Whether the type is for a variadic argument.
41
    /// * `allow_null` - Whether the type should allow null to be passed in
42
    ///   place.
43
    #[must_use]
44
    pub fn empty_from_type(
8✔
45
        type_: DataType,
46
        pass_by_ref: bool,
47
        is_variadic: bool,
48
        allow_null: bool,
49
    ) -> Option<Self> {
50
        match type_ {
×
51
            DataType::Object(Some(class)) => {
×
52
                Self::empty_from_class_type(class, pass_by_ref, is_variadic, allow_null)
53
            }
54
            type_ => Some(Self::empty_from_primitive_type(
24✔
55
                type_,
16✔
56
                pass_by_ref,
16✔
57
                is_variadic,
8✔
58
                allow_null,
8✔
59
            )),
60
        }
61
    }
62

63
    /// Attempts to create a zend type for a class object type. Returns an
64
    /// option containing the type if successful.
65
    ///
66
    /// Returns [`None`] if the data type was a class object where the class
67
    /// name could not be converted into a C string (i.e. contained
68
    /// NUL-bytes).
69
    ///
70
    /// # Parameters
71
    ///
72
    /// * `class_name` - Name of the class parameter.
73
    /// * `pass_by_ref` - Whether the type should be passed by reference.
74
    /// * `is_variadic` - Whether the type is for a variadic argument.
75
    /// * `allow_null` - Whether the type should allow null to be passed in
76
    ///   place.
77
    fn empty_from_class_type(
×
78
        class_name: &str,
79
        pass_by_ref: bool,
80
        is_variadic: bool,
81
        allow_null: bool,
82
    ) -> Option<Self> {
83
        let mut flags = Self::arg_info_flags(pass_by_ref, is_variadic);
×
84
        if allow_null {
×
85
            flags |= _ZEND_TYPE_NULLABLE_BIT;
×
86
        }
87
        cfg_if::cfg_if! {
88
            if #[cfg(php83)] {
89
                flags |= crate::ffi::_ZEND_TYPE_LITERAL_NAME_BIT
×
90
            } else {
91
                flags |= crate::ffi::_ZEND_TYPE_NAME_BIT
92
            }
93
        }
94

95
        Some(Self {
96
            ptr: std::ffi::CString::new(class_name)
×
97
                .ok()?
×
98
                .into_raw()
×
99
                .cast::<c_void>(),
100
            type_mask: flags,
101
        })
102
    }
103

104
    /// Attempts to create a zend type for a primitive PHP type.
105
    ///
106
    /// # Parameters
107
    ///
108
    /// * `type_` - Data type to create zend type for.
109
    /// * `pass_by_ref` - Whether the type should be passed by reference.
110
    /// * `is_variadic` - Whether the type is for a variadic argument.
111
    /// * `allow_null` - Whether the type should allow null to be passed in
112
    ///   place.
113
    ///
114
    /// # Panics
115
    ///
116
    /// Panics if the given `type_` is for a class object type.
117
    fn empty_from_primitive_type(
8✔
118
        type_: DataType,
119
        pass_by_ref: bool,
120
        is_variadic: bool,
121
        allow_null: bool,
122
    ) -> Self {
123
        assert!(!matches!(type_, DataType::Object(Some(_))));
16✔
124
        Self {
125
            ptr: ptr::null_mut::<c_void>(),
8✔
126
            type_mask: Self::type_init_code(type_, pass_by_ref, is_variadic, allow_null),
8✔
127
        }
128
    }
129

130
    /// Calculates the internal flags of the type.
131
    /// Translation of of the `_ZEND_ARG_INFO_FLAGS` macro from
132
    /// `zend_API.h:110`.
133
    ///
134
    /// # Parameters
135
    ///
136
    /// * `pass_by_ref` - Whether the value should be passed by reference.
137
    /// * `is_variadic` - Whether this type represents a variadic argument.
138
    pub(crate) fn arg_info_flags(pass_by_ref: bool, is_variadic: bool) -> u32 {
9✔
139
        (u32::from(pass_by_ref) << _ZEND_SEND_MODE_SHIFT)
9✔
140
            | (if is_variadic {
9✔
141
                _ZEND_IS_VARIADIC_BIT
1✔
142
            } else {
143
                0
8✔
144
            })
145
    }
146

147
    /// Calculates the internal flags of the type.
148
    /// Translation of the `ZEND_TYPE_INIT_CODE` macro from `zend_API.h:163`.
149
    ///
150
    /// # Parameters
151
    ///
152
    /// * `type_` - The type to initialize the Zend type with.
153
    /// * `pass_by_ref` - Whether the value should be passed by reference.
154
    /// * `is_variadic` - Whether this type represents a variadic argument.
155
    /// * `allow_null` - Whether the value can be null.
156
    pub(crate) fn type_init_code(
8✔
157
        type_: DataType,
158
        pass_by_ref: bool,
159
        is_variadic: bool,
160
        allow_null: bool,
161
    ) -> u32 {
162
        let type_ = type_.as_u32();
24✔
163

164
        (if type_ == _IS_BOOL {
8✔
165
            MAY_BE_BOOL
×
166
        } else if type_ == IS_MIXED {
8✔
167
            MAY_BE_ANY
2✔
168
        } else {
169
            1 << type_
6✔
170
        }) | (if allow_null {
8✔
UNCOV
171
            _ZEND_TYPE_NULLABLE_BIT
×
172
        } else {
173
            0
8✔
174
        }) | Self::arg_info_flags(pass_by_ref, is_variadic)
24✔
175
    }
176
}
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