mirror of
https://github.com/danog/ext-php-rs.git
synced 2024-11-27 04:24:54 +01:00
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.
This commit is contained in:
parent
35808d9e49
commit
349d497793
@ -2,8 +2,9 @@ use ext_php_rs::{
|
|||||||
call_user_func, info_table_end, info_table_row, info_table_start, parse_args,
|
call_user_func, info_table_end, info_table_row, info_table_start, parse_args,
|
||||||
php::{
|
php::{
|
||||||
args::{Arg, ArgParser},
|
args::{Arg, ArgParser},
|
||||||
class::ClassBuilder,
|
class::{ClassBuilder, ClassEntry},
|
||||||
enums::DataType,
|
enums::DataType,
|
||||||
|
exceptions::throw,
|
||||||
execution_data::ExecutionData,
|
execution_data::ExecutionData,
|
||||||
flags::MethodFlags,
|
flags::MethodFlags,
|
||||||
function::FunctionBuilder,
|
function::FunctionBuilder,
|
||||||
@ -148,6 +149,8 @@ pub extern "C" fn skeleton_version(execute_data: &mut ExecutionData, _retval: &m
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw(ClassEntry::exception(), "Hello!");
|
||||||
|
|
||||||
let result = format!(
|
let result = format!(
|
||||||
"x: {}, y: {}, z: {}",
|
"x: {}, y: {}, z: {}",
|
||||||
x.val::<ZendLong>().unwrap_or_default(),
|
x.val::<ZendLong>().unwrap_or_default(),
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
$x = new TestClass();
|
$x = new TestClass();
|
||||||
|
|
||||||
|
skeleton_version(1, 2);
|
||||||
|
|
||||||
var_dump($x->call(function ($v1, $v2) {
|
var_dump($x->call(function ($v1, $v2) {
|
||||||
// var_dump($v1, $v2);
|
// var_dump($v1, $v2);
|
||||||
// echo "Hello, world! I'm a callable.".PHP_EOL;
|
// echo "Hello, world! I'm a callable.".PHP_EOL;
|
||||||
// return "Ok rust";
|
// return "Ok rust";
|
||||||
return 0;
|
return 0;
|
||||||
}));
|
}));
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
//! Contains all the base PHP throwables, including `Throwable` and `Exception`.
|
|
||||||
|
|
||||||
use super::class::ClassEntry;
|
|
||||||
use crate::bindings::{
|
|
||||||
zend_ce_argument_count_error, zend_ce_arithmetic_error, zend_ce_compile_error,
|
|
||||||
zend_ce_division_by_zero_error, zend_ce_error_exception, zend_ce_exception,
|
|
||||||
zend_ce_parse_error, zend_ce_throwable, zend_ce_type_error, zend_ce_unhandled_match_error,
|
|
||||||
zend_ce_value_error,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl ClassEntry {
|
|
||||||
/// Returns the base `Throwable` class.
|
|
||||||
pub fn throwable<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_throwable.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `Exception` class.
|
|
||||||
pub fn exception<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_exception.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `ErrorException` class.
|
|
||||||
pub fn error_exception<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_error_exception.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `CompileError` class.
|
|
||||||
pub fn compile_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_compile_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `ParseError` class.
|
|
||||||
pub fn parse_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_parse_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `TypeError` class.
|
|
||||||
pub fn type_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_type_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `ArgumentCountError` class.
|
|
||||||
pub fn argument_count_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_argument_count_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `ValueError` class.
|
|
||||||
pub fn value_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_value_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `ArithmeticError` class.
|
|
||||||
pub fn arithmetic_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_arithmetic_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `DivisionByZeroError` class.
|
|
||||||
pub fn division_by_zero_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_division_by_zero_error.as_ref() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the base `UnhandledMatchError` class.
|
|
||||||
pub fn unhandled_match_error<'a>() -> Option<&'a Self> {
|
|
||||||
unsafe { zend_ce_unhandled_match_error.as_ref() }
|
|
||||||
}
|
|
||||||
}
|
|
117
src/php/exceptions.rs
Normal file
117
src/php/exceptions.rs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
//! Contains all the base PHP throwables, including `Throwable` and `Exception`.
|
||||||
|
|
||||||
|
use super::class::ClassEntry;
|
||||||
|
use crate::{
|
||||||
|
bindings::{
|
||||||
|
zend_ce_argument_count_error, zend_ce_arithmetic_error, zend_ce_compile_error,
|
||||||
|
zend_ce_division_by_zero_error, zend_ce_error_exception, zend_ce_exception,
|
||||||
|
zend_ce_parse_error, zend_ce_throwable, zend_ce_type_error, zend_ce_unhandled_match_error,
|
||||||
|
zend_ce_value_error, zend_throw_exception_ex,
|
||||||
|
},
|
||||||
|
functions::c_str,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Throws an exception with a given message. See [`ClassEntry`] for some built-in exception
|
||||||
|
/// types.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
///
|
||||||
|
/// * `ex` - The exception type to throw.
|
||||||
|
/// * `message` - The message to display when throwing the exception.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use ext_php_rs::php::{class::ClassEntry, exceptions::throw};
|
||||||
|
///
|
||||||
|
/// throw(ClassEntry::compile_error(), "This is a CompileError.");
|
||||||
|
/// ```
|
||||||
|
pub fn throw(ex: &ClassEntry, message: &str) {
|
||||||
|
throw_with_code(ex, 0, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Throws an exception with a given message and status code. See [`ClassEntry`] for some built-in
|
||||||
|
/// exception types.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
///
|
||||||
|
/// * `ex` - The exception type to throw.
|
||||||
|
/// * `code` - The status code to use when throwing the exception.
|
||||||
|
/// * `message` - The message to display when throwing the exception.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use ext_php_rs::php::{class::ClassEntry, exceptions::throw_with_code};
|
||||||
|
///
|
||||||
|
/// throw_with_code(ClassEntry::compile_error(), 123, "This is a CompileError.");
|
||||||
|
/// ```
|
||||||
|
pub fn throw_with_code(ex: &ClassEntry, code: i32, message: &str) {
|
||||||
|
// SAFETY: We are given a reference to a `ClassEntry` therefore when we cast it to a pointer it
|
||||||
|
// will be valid.
|
||||||
|
unsafe {
|
||||||
|
zend_throw_exception_ex(
|
||||||
|
(ex as *const _) as *mut _,
|
||||||
|
code as _,
|
||||||
|
c_str("%s"),
|
||||||
|
c_str(message),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClassEntry {
|
||||||
|
/// Returns the base `Throwable` class.
|
||||||
|
pub fn throwable() -> &'static Self {
|
||||||
|
unsafe { zend_ce_throwable.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `Exception` class.
|
||||||
|
pub fn exception() -> &'static Self {
|
||||||
|
unsafe { zend_ce_exception.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `ErrorException` class.
|
||||||
|
pub fn error_exception() -> &'static Self {
|
||||||
|
unsafe { zend_ce_error_exception.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `CompileError` class.
|
||||||
|
pub fn compile_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_compile_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `ParseError` class.
|
||||||
|
pub fn parse_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_parse_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `TypeError` class.
|
||||||
|
pub fn type_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_type_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `ArgumentCountError` class.
|
||||||
|
pub fn argument_count_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_argument_count_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `ValueError` class.
|
||||||
|
pub fn value_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_value_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `ArithmeticError` class.
|
||||||
|
pub fn arithmetic_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_arithmetic_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `DivisionByZeroError` class.
|
||||||
|
pub fn division_by_zero_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_division_by_zero_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base `UnhandledMatchError` class.
|
||||||
|
pub fn unhandled_match_error() -> &'static Self {
|
||||||
|
unsafe { zend_ce_unhandled_match_error.as_ref() }.unwrap()
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
pub mod args;
|
pub mod args;
|
||||||
pub mod class;
|
pub mod class;
|
||||||
pub mod enums;
|
pub mod enums;
|
||||||
pub mod errors;
|
pub mod exceptions;
|
||||||
pub mod execution_data;
|
pub mod execution_data;
|
||||||
pub mod flags;
|
pub mod flags;
|
||||||
pub mod function;
|
pub mod function;
|
||||||
|
Loading…
Reference in New Issue
Block a user