mirror of
https://github.com/danog/ext-php-rs.git
synced 2024-12-02 09:37:51 +01:00
Remove lifetime from PhpException
(#80)
* Remove lifetime from `PhpException` All class entries are effectively static (module start to module end) so it's just a hassle carrying the lifetime everywhere. * Removed forgotten lifetimes * Implement `IntoZval` for `Result<T, E>` Fixes function return error with `PhpResult` as the return type * Updated changelog
This commit is contained in:
parent
1e41b50100
commit
daef57ba91
@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
- `PhpException` no longer requires a lifetime [#80].
|
||||||
|
- Added `PhpException` and `PhpResult` to prelude [#80].
|
||||||
|
|
||||||
|
[#80]: https://github.com/davidcole1340/ext-php-rs/pull/80
|
||||||
|
|
||||||
## Version 0.5.0
|
## Version 0.5.0
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
@ -60,7 +60,6 @@ pub fn parser(args: AttributeArgs, input: ItemFn) -> Result<(TokenStream, Functi
|
|||||||
let arg_parser = build_arg_parser(args.iter(), &optional)?;
|
let arg_parser = build_arg_parser(args.iter(), &optional)?;
|
||||||
let arg_accessors = build_arg_accessors(&args);
|
let arg_accessors = build_arg_accessors(&args);
|
||||||
|
|
||||||
let return_handler = build_return_handler(output);
|
|
||||||
let return_type = get_return_type(output)?;
|
let return_type = get_return_type(output)?;
|
||||||
|
|
||||||
let func = quote! {
|
let func = quote! {
|
||||||
@ -75,7 +74,10 @@ pub fn parser(args: AttributeArgs, input: ItemFn) -> Result<(TokenStream, Functi
|
|||||||
|
|
||||||
let result = #ident(#(#arg_accessors, )*);
|
let result = #ident(#(#arg_accessors, )*);
|
||||||
|
|
||||||
#return_handler
|
if let Err(e) = result.set_zval(retval, false) {
|
||||||
|
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
|
||||||
|
e.throw().expect("Failed to throw exception");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,61 +204,6 @@ fn build_arg_accessors(args: &[Arg]) -> Vec<TokenStream> {
|
|||||||
args.iter().map(|arg| arg.get_accessor()).collect()
|
args.iter().map(|arg| arg.get_accessor()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_return_handler(output_type: &ReturnType) -> TokenStream {
|
|
||||||
let handler = match output_type {
|
|
||||||
ReturnType::Default => Some(quote! { retval.set_null(); }),
|
|
||||||
ReturnType::Type(_, ref ty) => match **ty {
|
|
||||||
Type::Path(ref path) => match path.path.segments.last() {
|
|
||||||
Some(path_seg) => match path_seg.ident.to_string().as_ref() {
|
|
||||||
"Result" => Some(quote! {
|
|
||||||
match result {
|
|
||||||
Ok(result) => match result.set_zval(retval, false) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
|
|
||||||
e.throw().expect("Failed to throw exception: Failed to set return value.");
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
|
|
||||||
e.throw().expect("Failed to throw exception: Error type returned from internal function.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
"Option" => Some(quote! {
|
|
||||||
match result {
|
|
||||||
Some(result) => match result.set_zval(retval, false) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
|
|
||||||
e.throw().expect("Failed to throw exception: Failed to set return value.");
|
|
||||||
},
|
|
||||||
},
|
|
||||||
None => retval.set_null(),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
match handler {
|
|
||||||
Some(handler) => handler,
|
|
||||||
None => quote! {
|
|
||||||
match result.set_zval(retval, false) {
|
|
||||||
Ok(_) => {},
|
|
||||||
Err(e) => {
|
|
||||||
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
|
|
||||||
e.throw().expect("Failed to throw exception: Failed to set return value.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_return_type(output_type: &ReturnType) -> Result<Option<(String, bool)>> {
|
pub fn get_return_type(output_type: &ReturnType) -> Result<Option<(String, bool)>> {
|
||||||
Ok(match output_type {
|
Ok(match output_type {
|
||||||
ReturnType::Default => None,
|
ReturnType::Default => None,
|
||||||
|
@ -114,7 +114,6 @@ pub fn parser(input: &mut ImplItemMethod, rename_rule: RenameRule) -> Result<Par
|
|||||||
let (arg_definitions, is_static) = build_arg_definitions(&args);
|
let (arg_definitions, is_static) = build_arg_definitions(&args);
|
||||||
let arg_parser = build_arg_parser(args.iter(), &optional)?;
|
let arg_parser = build_arg_parser(args.iter(), &optional)?;
|
||||||
let arg_accessors = build_arg_accessors(&args);
|
let arg_accessors = build_arg_accessors(&args);
|
||||||
let return_handler = function::build_return_handler(output);
|
|
||||||
let this = if is_static {
|
let this = if is_static {
|
||||||
quote! { Self:: }
|
quote! { Self:: }
|
||||||
} else {
|
} else {
|
||||||
@ -133,7 +132,10 @@ pub fn parser(input: &mut ImplItemMethod, rename_rule: RenameRule) -> Result<Par
|
|||||||
|
|
||||||
let result = #this #ident(#(#arg_accessors, )*);
|
let result = #this #ident(#(#arg_accessors, )*);
|
||||||
|
|
||||||
#return_handler
|
if let Err(e) = result.set_zval(retval, false) {
|
||||||
|
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
|
||||||
|
e.throw().expect("Failed to throw exception");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ pub struct RedisException;
|
|||||||
|
|
||||||
// Throw our newly created exception
|
// Throw our newly created exception
|
||||||
#[php_function]
|
#[php_function]
|
||||||
pub fn throw_exception() -> Result<i32, PhpException<'static>> {
|
pub fn throw_exception() -> PhpResult<i32> {
|
||||||
Err(PhpException::from_class::<RedisException>("Not good!".into()))
|
Err(PhpException::from_class::<RedisException>("Not good!".into()))
|
||||||
}
|
}
|
||||||
# #[php_module]
|
# #[php_module]
|
||||||
|
@ -95,7 +95,7 @@ impl From<NulError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<Error> for PhpException<'a> {
|
impl From<Error> for PhpException {
|
||||||
fn from(err: Error) -> Self {
|
fn from(err: Error) -> Self {
|
||||||
Self::default(err.to_string())
|
Self::default(err.to_string())
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,7 @@ pub use ext_php_rs_derive::php_module;
|
|||||||
/// pub struct Example;
|
/// pub struct Example;
|
||||||
///
|
///
|
||||||
/// #[php_function]
|
/// #[php_function]
|
||||||
/// pub fn throw_exception() -> Result<i32, PhpException<'static>> {
|
/// pub fn throw_exception() -> Result<i32, PhpException> {
|
||||||
/// Err(PhpException::from_class::<Example>("Bad things happen".into()))
|
/// Err(PhpException::from_class::<Example>("Bad things happen".into()))
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
@ -439,6 +439,7 @@ pub use ext_php_rs_derive::php_startup;
|
|||||||
|
|
||||||
/// A module typically glob-imported containing the typically required macros and imports.
|
/// A module typically glob-imported containing the typically required macros and imports.
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
pub use crate::php::exceptions::{PhpException, PhpResult};
|
||||||
pub use crate::php::module::ModuleBuilder;
|
pub use crate::php::module::ModuleBuilder;
|
||||||
pub use crate::php::types::callable::Callable;
|
pub use crate::php::types::callable::Callable;
|
||||||
#[cfg(any(docs, feature = "closure"))]
|
#[cfg(any(docs, feature = "closure"))]
|
||||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Result type with the error variant as a [`PhpException`].
|
/// Result type with the error variant as a [`PhpException`].
|
||||||
pub type PhpResult<T = ()> = std::result::Result<T, PhpException<'static>>;
|
pub type PhpResult<T = ()> = std::result::Result<T, PhpException>;
|
||||||
|
|
||||||
/// Represents a PHP exception which can be thrown using the `throw()` function. Primarily used to
|
/// Represents a PHP exception which can be thrown using the `throw()` function. Primarily used to
|
||||||
/// return from a [`Result<T, PhpException>`] which can immediately be thrown by the `ext-php-rs`
|
/// return from a [`Result<T, PhpException>`] which can immediately be thrown by the `ext-php-rs`
|
||||||
@ -25,13 +25,13 @@ pub type PhpResult<T = ()> = std::result::Result<T, PhpException<'static>>;
|
|||||||
/// can also be returned from these functions. You can also implement [`From<T>`] for your custom
|
/// can also be returned from these functions. You can also implement [`From<T>`] for your custom
|
||||||
/// error type.
|
/// error type.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PhpException<'a> {
|
pub struct PhpException {
|
||||||
message: String,
|
message: String,
|
||||||
code: i32,
|
code: i32,
|
||||||
ex: &'a ClassEntry,
|
ex: &'static ClassEntry,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PhpException<'a> {
|
impl PhpException {
|
||||||
/// Creates a new exception instance.
|
/// Creates a new exception instance.
|
||||||
///
|
///
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
@ -39,7 +39,7 @@ impl<'a> PhpException<'a> {
|
|||||||
/// * `message` - Message to contain in the exception.
|
/// * `message` - Message to contain in the exception.
|
||||||
/// * `code` - Integer code to go inside the exception.
|
/// * `code` - Integer code to go inside the exception.
|
||||||
/// * `ex` - Exception type to throw.
|
/// * `ex` - Exception type to throw.
|
||||||
pub fn new(message: String, code: i32, ex: &'a ClassEntry) -> Self {
|
pub fn new(message: String, code: i32, ex: &'static ClassEntry) -> Self {
|
||||||
Self { message, code, ex }
|
Self { message, code, ex }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +69,13 @@ impl<'a> PhpException<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<String> for PhpException<'a> {
|
impl From<String> for PhpException {
|
||||||
fn from(str: String) -> Self {
|
fn from(str: String) -> Self {
|
||||||
Self::default(str)
|
Self::default(str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&str> for PhpException<'a> {
|
impl From<&str> for PhpException {
|
||||||
fn from(str: &str) -> Self {
|
fn from(str: &str) -> Self {
|
||||||
Self::default(str.into())
|
Self::default(str.into())
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ use crate::{
|
|||||||
php::{
|
php::{
|
||||||
class::ClassEntry,
|
class::ClassEntry,
|
||||||
enums::DataType,
|
enums::DataType,
|
||||||
exceptions::PhpException,
|
exceptions::PhpResult,
|
||||||
flags::ZvalTypeFlags,
|
flags::ZvalTypeFlags,
|
||||||
types::{array::OwnedHashTable, string::ZendString},
|
types::{array::OwnedHashTable, string::ZendString},
|
||||||
},
|
},
|
||||||
@ -649,7 +649,7 @@ impl ZendObjectHandlers {
|
|||||||
type_: c_int,
|
type_: c_int,
|
||||||
cache_slot: *mut *mut c_void,
|
cache_slot: *mut *mut c_void,
|
||||||
rv: *mut Zval,
|
rv: *mut Zval,
|
||||||
) -> std::result::Result<*mut Zval, PhpException<'static>> {
|
) -> PhpResult<*mut Zval> {
|
||||||
let obj = object
|
let obj = object
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
||||||
@ -696,7 +696,7 @@ impl ZendObjectHandlers {
|
|||||||
member: *mut zend_string,
|
member: *mut zend_string,
|
||||||
value: *mut Zval,
|
value: *mut Zval,
|
||||||
cache_slot: *mut *mut c_void,
|
cache_slot: *mut *mut c_void,
|
||||||
) -> std::result::Result<*mut Zval, PhpException<'static>> {
|
) -> PhpResult<*mut Zval> {
|
||||||
let obj = object
|
let obj = object
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
||||||
@ -734,7 +734,7 @@ impl ZendObjectHandlers {
|
|||||||
unsafe fn internal<T: RegisteredClass>(
|
unsafe fn internal<T: RegisteredClass>(
|
||||||
object: *mut zend_object,
|
object: *mut zend_object,
|
||||||
props: &mut HashTable,
|
props: &mut HashTable,
|
||||||
) -> std::result::Result<(), PhpException<'static>> {
|
) -> PhpResult {
|
||||||
let obj = object
|
let obj = object
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
||||||
@ -779,7 +779,7 @@ impl ZendObjectHandlers {
|
|||||||
member: *mut zend_string,
|
member: *mut zend_string,
|
||||||
has_set_exists: c_int,
|
has_set_exists: c_int,
|
||||||
cache_slot: *mut *mut c_void,
|
cache_slot: *mut *mut c_void,
|
||||||
) -> std::result::Result<c_int, PhpException<'static>> {
|
) -> PhpResult<c_int> {
|
||||||
let obj = object
|
let obj = object
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
zend_value, zval, zval_ptr_dtor,
|
zend_value, zval, zval_ptr_dtor,
|
||||||
},
|
},
|
||||||
errors::{Error, Result},
|
errors::{Error, Result},
|
||||||
php::pack::Pack,
|
php::{exceptions::PhpException, pack::Pack},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::php::{
|
use crate::php::{
|
||||||
@ -692,6 +692,24 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, E> IntoZval for std::result::Result<T, E>
|
||||||
|
where
|
||||||
|
T: IntoZval,
|
||||||
|
E: Into<PhpException>,
|
||||||
|
{
|
||||||
|
const TYPE: DataType = T::TYPE;
|
||||||
|
|
||||||
|
fn set_zval(self, zv: &mut Zval, persistent: bool) -> Result<()> {
|
||||||
|
match self {
|
||||||
|
Ok(val) => val.set_zval(zv, persistent),
|
||||||
|
Err(e) => {
|
||||||
|
let ex: PhpException = e.into();
|
||||||
|
ex.throw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Allows zvals to be converted into Rust types in a fallible way. Reciprocal of the [`IntoZval`]
|
/// Allows zvals to be converted into Rust types in a fallible way. Reciprocal of the [`IntoZval`]
|
||||||
/// trait.
|
/// trait.
|
||||||
pub trait FromZval<'a>: Sized {
|
pub trait FromZval<'a>: Sized {
|
||||||
|
Loading…
Reference in New Issue
Block a user