Skip to content

Commit 349d497

Browse files
Added ability to throw exceptions (#21)
* Exceptions have static lifetimes * Added functions for throwing exceptions Changed the `ClassEntry` implementation to unwrap the result before returning, as these types are guaranteed to be valid. Also replaced the 'a lifetime with 'static lifetimes.
1 parent 35808d9 commit 349d497

File tree

5 files changed

+125
-69
lines changed

5 files changed

+125
-69
lines changed

example/skel/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use ext_php_rs::{
22
call_user_func, info_table_end, info_table_row, info_table_start, parse_args,
33
php::{
44
args::{Arg, ArgParser},
5-
class::ClassBuilder,
5+
class::{ClassBuilder, ClassEntry},
66
enums::DataType,
7+
exceptions::throw,
78
execution_data::ExecutionData,
89
flags::MethodFlags,
910
function::FunctionBuilder,
@@ -148,6 +149,8 @@ pub extern "C" fn skeleton_version(execute_data: &mut ExecutionData, _retval: &m
148149
return;
149150
}
150151

152+
throw(ClassEntry::exception(), "Hello!");
153+
151154
let result = format!(
152155
"x: {}, y: {}, z: {}",
153156
x.val::<ZendLong>().unwrap_or_default(),

example/skel/test.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
$x = new TestClass();
44

5+
skeleton_version(1, 2);
6+
57
var_dump($x->call(function ($v1, $v2) {
68
// var_dump($v1, $v2);
79
// echo "Hello, world! I'm a callable.".PHP_EOL;
810
// return "Ok rust";
911
return 0;
10-
}));
12+
}));

src/php/errors.rs

Lines changed: 0 additions & 66 deletions
This file was deleted.

src/php/exceptions.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//! Contains all the base PHP throwables, including `Throwable` and `Exception`.
2+
3+
use super::class::ClassEntry;
4+
use crate::{
5+
bindings::{
6+
zend_ce_argument_count_error, zend_ce_arithmetic_error, zend_ce_compile_error,
7+
zend_ce_division_by_zero_error, zend_ce_error_exception, zend_ce_exception,
8+
zend_ce_parse_error, zend_ce_throwable, zend_ce_type_error, zend_ce_unhandled_match_error,
9+
zend_ce_value_error, zend_throw_exception_ex,
10+
},
11+
functions::c_str,
12+
};
13+
14+
/// Throws an exception with a given message. See [`ClassEntry`] for some built-in exception
15+
/// types.
16+
///
17+
/// # Parameters
18+
///
19+
/// * `ex` - The exception type to throw.
20+
/// * `message` - The message to display when throwing the exception.
21+
///
22+
/// # Examples
23+
///
24+
/// ```no_run
25+
/// use ext_php_rs::php::{class::ClassEntry, exceptions::throw};
26+
///
27+
/// throw(ClassEntry::compile_error(), "This is a CompileError.");
28+
/// ```
29+
pub fn throw(ex: &ClassEntry, message: &str) {
30+
throw_with_code(ex, 0, message);
31+
}
32+
33+
/// Throws an exception with a given message and status code. See [`ClassEntry`] for some built-in
34+
/// exception types.
35+
///
36+
/// # Parameters
37+
///
38+
/// * `ex` - The exception type to throw.
39+
/// * `code` - The status code to use when throwing the exception.
40+
/// * `message` - The message to display when throwing the exception.
41+
///
42+
/// # Examples
43+
///
44+
/// ```no_run
45+
/// use ext_php_rs::php::{class::ClassEntry, exceptions::throw_with_code};
46+
///
47+
/// throw_with_code(ClassEntry::compile_error(), 123, "This is a CompileError.");
48+
/// ```
49+
pub fn throw_with_code(ex: &ClassEntry, code: i32, message: &str) {
50+
// SAFETY: We are given a reference to a `ClassEntry` therefore when we cast it to a pointer it
51+
// will be valid.
52+
unsafe {
53+
zend_throw_exception_ex(
54+
(ex as *const _) as *mut _,
55+
code as _,
56+
c_str("%s"),
57+
c_str(message),
58+
)
59+
};
60+
}
61+
62+
impl ClassEntry {
63+
/// Returns the base `Throwable` class.
64+
pub fn throwable() -> &'static Self {
65+
unsafe { zend_ce_throwable.as_ref() }.unwrap()
66+
}
67+
68+
/// Returns the base `Exception` class.
69+
pub fn exception() -> &'static Self {
70+
unsafe { zend_ce_exception.as_ref() }.unwrap()
71+
}
72+
73+
/// Returns the base `ErrorException` class.
74+
pub fn error_exception() -> &'static Self {
75+
unsafe { zend_ce_error_exception.as_ref() }.unwrap()
76+
}
77+
78+
/// Returns the base `CompileError` class.
79+
pub fn compile_error() -> &'static Self {
80+
unsafe { zend_ce_compile_error.as_ref() }.unwrap()
81+
}
82+
83+
/// Returns the base `ParseError` class.
84+
pub fn parse_error() -> &'static Self {
85+
unsafe { zend_ce_parse_error.as_ref() }.unwrap()
86+
}
87+
88+
/// Returns the base `TypeError` class.
89+
pub fn type_error() -> &'static Self {
90+
unsafe { zend_ce_type_error.as_ref() }.unwrap()
91+
}
92+
93+
/// Returns the base `ArgumentCountError` class.
94+
pub fn argument_count_error() -> &'static Self {
95+
unsafe { zend_ce_argument_count_error.as_ref() }.unwrap()
96+
}
97+
98+
/// Returns the base `ValueError` class.
99+
pub fn value_error() -> &'static Self {
100+
unsafe { zend_ce_value_error.as_ref() }.unwrap()
101+
}
102+
103+
/// Returns the base `ArithmeticError` class.
104+
pub fn arithmetic_error() -> &'static Self {
105+
unsafe { zend_ce_arithmetic_error.as_ref() }.unwrap()
106+
}
107+
108+
/// Returns the base `DivisionByZeroError` class.
109+
pub fn division_by_zero_error() -> &'static Self {
110+
unsafe { zend_ce_division_by_zero_error.as_ref() }.unwrap()
111+
}
112+
113+
/// Returns the base `UnhandledMatchError` class.
114+
pub fn unhandled_match_error() -> &'static Self {
115+
unsafe { zend_ce_unhandled_match_error.as_ref() }.unwrap()
116+
}
117+
}

src/php/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
pub mod args;
44
pub mod class;
55
pub mod enums;
6-
pub mod errors;
6+
pub mod exceptions;
77
pub mod execution_data;
88
pub mod flags;
99
pub mod function;

0 commit comments

Comments
 (0)