Skip to main content

ext_php_rs/zend/
ce.rs

1//! Stock class entries registered with PHP, primarily exceptions.
2//!
3//! A class entry is valid only until the module shuts down. A SAPI that starts
4//! the module again in the same process (`FrankenPHP` worker restarts) makes new
5//! class entries. Do not keep a returned reference in a `static`: call the
6//! function again each time.
7
8#![allow(clippy::unwrap_used)]
9
10use crate::ffi::{
11    zend_ce_aggregate, zend_ce_argument_count_error, zend_ce_arithmetic_error, zend_ce_arrayaccess,
12    zend_ce_compile_error, zend_ce_countable, zend_ce_division_by_zero_error, zend_ce_error,
13    zend_ce_error_exception, zend_ce_exception, zend_ce_iterator, zend_ce_parse_error,
14    zend_ce_serializable, zend_ce_stringable, zend_ce_throwable, zend_ce_traversable,
15    zend_ce_type_error, zend_ce_unhandled_match_error, zend_ce_value_error,
16    zend_standard_class_def,
17};
18
19use super::ClassEntry;
20
21/// Returns the base [`stdClass`](https://www.php.net/manual/en/class.stdclass.php) class.
22///
23/// # Panics
24///
25/// If stdclass [`ClassEntry`] is not available
26pub fn stdclass() -> &'static ClassEntry {
27    unsafe { zend_standard_class_def.as_ref() }.unwrap()
28}
29
30/// Returns the base [`Throwable`](https://www.php.net/manual/en/class.throwable.php) class.
31///
32/// # Panics
33///
34/// If throwable [`ClassEntry`] is not available
35pub fn throwable() -> &'static ClassEntry {
36    unsafe { zend_ce_throwable.as_ref() }.unwrap()
37}
38
39/// Returns the base [`Exception`](https://www.php.net/manual/en/class.exception.php) class.
40///
41/// # Panics
42///
43/// If exception [`ClassEntry`] is not available
44pub fn exception() -> &'static ClassEntry {
45    unsafe { zend_ce_exception.as_ref() }.unwrap()
46}
47
48/// Returns the base [`Error`](https://www.php.net/manual/en/class.error.php) class.
49///
50/// # Panics
51///
52/// If error [`ClassEntry`] is not available
53pub fn error() -> &'static ClassEntry {
54    unsafe { zend_ce_error.as_ref() }.unwrap()
55}
56
57/// Returns the base [`ErrorException`](https://www.php.net/manual/en/class.errorexception.php) class.
58///
59/// # Panics
60///
61/// If error exception [`ClassEntry`] is not available
62pub fn error_exception() -> &'static ClassEntry {
63    unsafe { zend_ce_error_exception.as_ref() }.unwrap()
64}
65
66/// Returns the base [`CompileError`](https://www.php.net/manual/en/class.compileerror.php) class.
67///
68/// # Panics
69///
70/// If compile error [`ClassEntry`] is not available
71pub fn compile_error() -> &'static ClassEntry {
72    unsafe { zend_ce_compile_error.as_ref() }.unwrap()
73}
74
75/// Returns the base [`ParseError`](https://www.php.net/manual/en/class.parseerror.php) class.
76///
77/// # Panics
78///
79/// If parse error [`ClassEntry`] is not available
80pub fn parse_error() -> &'static ClassEntry {
81    unsafe { zend_ce_parse_error.as_ref() }.unwrap()
82}
83
84/// Returns the base [`TypeError`](https://www.php.net/manual/en/class.typeerror.php) class.
85///
86/// # Panics
87///
88/// If type error [`ClassEntry`] is not available
89pub fn type_error() -> &'static ClassEntry {
90    unsafe { zend_ce_type_error.as_ref() }.unwrap()
91}
92
93/// Returns the base [`ArgumentCountError`](https://www.php.net/manual/en/class.argumentcounterror.php) class.
94///
95/// # Panics
96///
97/// If argument count error [`ClassEntry`] is not available
98pub fn argument_count_error() -> &'static ClassEntry {
99    unsafe { zend_ce_argument_count_error.as_ref() }.unwrap()
100}
101
102/// Returns the base [`ValueError`](https://www.php.net/manual/en/class.valueerror.php) class.
103///
104/// # Panics
105///
106/// If value error [`ClassEntry`] is not available
107pub fn value_error() -> &'static ClassEntry {
108    unsafe { zend_ce_value_error.as_ref() }.unwrap()
109}
110
111/// Returns the base [`ArithmeticError`](https://www.php.net/manual/en/class.arithmeticerror.php) class.
112///
113/// # Panics
114///
115/// If arithmetic error [`ClassEntry`] is not available
116pub fn arithmetic_error() -> &'static ClassEntry {
117    unsafe { zend_ce_arithmetic_error.as_ref() }.unwrap()
118}
119
120/// Returns the base [`DivisionByZeroError`](https://www.php.net/manual/en/class.divisionbyzeroerror.php) class.
121///
122/// # Panics
123///
124/// If division by zero error [`ClassEntry`] is not available
125pub fn division_by_zero_error() -> &'static ClassEntry {
126    unsafe { zend_ce_division_by_zero_error.as_ref() }.unwrap()
127}
128
129/// Returns the base [`UnhandledMatchError`](https://www.php.net/manual/en/class.unhandledmatcherror.php) class.
130///
131/// # Panics
132///
133/// If unhandled match error [`ClassEntry`] is not available
134pub fn unhandled_match_error() -> &'static ClassEntry {
135    unsafe { zend_ce_unhandled_match_error.as_ref() }.unwrap()
136}
137
138/// Returns the [`Traversable`](https://www.php.net/manual/en/class.traversable.php) interface.
139///
140/// # Panics
141///
142/// If traversable [`ClassEntry`] is not available
143pub fn traversable() -> &'static ClassEntry {
144    unsafe { zend_ce_traversable.as_ref() }.unwrap()
145}
146
147/// Returns the [`IteratorAggregate`](https://www.php.net/manual/en/class.iteratoraggregate.php) interface.
148///
149/// # Panics
150///
151/// If aggregate [`ClassEntry`] is not available
152pub fn aggregate() -> &'static ClassEntry {
153    unsafe { zend_ce_aggregate.as_ref() }.unwrap()
154}
155
156/// Returns the [`Iterator`](https://www.php.net/manual/en/class.iterator.php) interface.
157///
158/// # Panics
159///
160/// If iterator [`ClassEntry`] is not available
161pub fn iterator() -> &'static ClassEntry {
162    unsafe { zend_ce_iterator.as_ref() }.unwrap()
163}
164
165/// Returns the [`ArrayAccess`](https://www.php.net/manual/en/class.arrayaccess.php) interface.
166///
167/// # Panics
168///
169/// If arrayaccess [`ClassEntry`] is not available
170pub fn arrayaccess() -> &'static ClassEntry {
171    unsafe { zend_ce_arrayaccess.as_ref() }.unwrap()
172}
173
174/// Returns the [`Serializable`](https://www.php.net/manual/en/class.serializable.php) interface.
175///
176/// # Panics
177///
178/// If serializable [`ClassEntry`] is not available
179pub fn serializable() -> &'static ClassEntry {
180    unsafe { zend_ce_serializable.as_ref() }.unwrap()
181}
182
183/// Returns the [`Countable`](https://www.php.net/manual/en/class.countable.php) interface.
184///
185/// # Panics
186///
187/// If countable [`ClassEntry`] is not available
188pub fn countable() -> &'static ClassEntry {
189    unsafe { zend_ce_countable.as_ref() }.unwrap()
190}
191
192/// Returns the [`Stringable`](https://www.php.net/manual/en/class.stringable.php) interface.
193///
194/// # Panics
195///
196/// If stringable [`ClassEntry`] is not available
197pub fn stringable() -> &'static ClassEntry {
198    unsafe { zend_ce_stringable.as_ref() }.unwrap()
199}
200
201#[cfg(test)]
202#[cfg(feature = "embed")]
203mod tests {
204    use super::*;
205    use crate::embed::Embed;
206
207    #[test]
208    fn test_stdclass() {
209        Embed::run(|| {
210            let stdclass = stdclass();
211            assert_eq!(stdclass.name(), Some("stdClass"));
212        });
213    }
214
215    #[test]
216    fn test_throwable() {
217        Embed::run(|| {
218            let throwable = throwable();
219            assert_eq!(throwable.name(), Some("Throwable"));
220        });
221    }
222
223    #[test]
224    fn test_exception() {
225        Embed::run(|| {
226            let exception = exception();
227            assert_eq!(exception.name(), Some("Exception"));
228        });
229    }
230
231    #[test]
232    fn test_error_exception() {
233        Embed::run(|| {
234            let error_exception = error_exception();
235            assert_eq!(error_exception.name(), Some("ErrorException"));
236        });
237    }
238
239    #[test]
240    fn test_compile_error() {
241        Embed::run(|| {
242            let compile_error = compile_error();
243            assert_eq!(compile_error.name(), Some("CompileError"));
244        });
245    }
246
247    #[test]
248    fn test_parse_error() {
249        Embed::run(|| {
250            let parse_error = parse_error();
251            assert_eq!(parse_error.name(), Some("ParseError"));
252        });
253    }
254
255    #[test]
256    fn test_type_error() {
257        Embed::run(|| {
258            let type_error = type_error();
259            assert_eq!(type_error.name(), Some("TypeError"));
260        });
261    }
262
263    #[test]
264    fn test_argument_count_error() {
265        Embed::run(|| {
266            let argument_count_error = argument_count_error();
267            assert_eq!(argument_count_error.name(), Some("ArgumentCountError"));
268        });
269    }
270
271    #[test]
272    fn test_value_error() {
273        Embed::run(|| {
274            let value_error = value_error();
275            assert_eq!(value_error.name(), Some("ValueError"));
276        });
277    }
278
279    #[test]
280    fn test_arithmetic_error() {
281        Embed::run(|| {
282            let arithmetic_error = arithmetic_error();
283            assert_eq!(arithmetic_error.name(), Some("ArithmeticError"));
284        });
285    }
286
287    #[test]
288    fn test_division_by_zero_error() {
289        Embed::run(|| {
290            let division_by_zero_error = division_by_zero_error();
291            assert_eq!(division_by_zero_error.name(), Some("DivisionByZeroError"));
292        });
293    }
294
295    #[test]
296    fn test_unhandled_match_error() {
297        Embed::run(|| {
298            let unhandled_match_error = unhandled_match_error();
299            assert_eq!(unhandled_match_error.name(), Some("UnhandledMatchError"));
300        });
301    }
302
303    #[test]
304    fn test_traversable() {
305        Embed::run(|| {
306            let traversable = traversable();
307            assert_eq!(traversable.name(), Some("Traversable"));
308        });
309    }
310
311    #[test]
312    fn test_aggregate() {
313        Embed::run(|| {
314            let aggregate = aggregate();
315            assert_eq!(aggregate.name(), Some("IteratorAggregate"));
316        });
317    }
318
319    #[test]
320    fn test_iterator() {
321        Embed::run(|| {
322            let iterator = iterator();
323            assert_eq!(iterator.name(), Some("Iterator"));
324        });
325    }
326
327    #[test]
328    fn test_arrayaccess() {
329        Embed::run(|| {
330            let arrayaccess = arrayaccess();
331            assert_eq!(arrayaccess.name(), Some("ArrayAccess"));
332        });
333    }
334
335    #[test]
336    fn test_serializable() {
337        Embed::run(|| {
338            let serializable = serializable();
339            assert_eq!(serializable.name(), Some("Serializable"));
340        });
341    }
342
343    #[test]
344    fn test_countable() {
345        Embed::run(|| {
346            let countable = countable();
347            assert_eq!(countable.name(), Some("Countable"));
348        });
349    }
350
351    #[test]
352    fn test_stringable() {
353        Embed::run(|| {
354            let stringable = stringable();
355            assert_eq!(stringable.name(), Some("Stringable"));
356        });
357    }
358}