Skip to content

Commit daef57b

Browse files
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
1 parent 1e41b50 commit daef57b

File tree

9 files changed

+48
-75
lines changed

9 files changed

+48
-75
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
- `PhpException` no longer requires a lifetime [#80].
4+
- Added `PhpException` and `PhpResult` to prelude [#80].
5+
6+
[#80]: https://github.com/davidcole1340/ext-php-rs/pull/80
7+
38
## Version 0.5.0
49

510
### Breaking changes

ext-php-rs-derive/src/function.rs

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ pub fn parser(args: AttributeArgs, input: ItemFn) -> Result<(TokenStream, Functi
6060
let arg_parser = build_arg_parser(args.iter(), &optional)?;
6161
let arg_accessors = build_arg_accessors(&args);
6262

63-
let return_handler = build_return_handler(output);
6463
let return_type = get_return_type(output)?;
6564

6665
let func = quote! {
@@ -75,7 +74,10 @@ pub fn parser(args: AttributeArgs, input: ItemFn) -> Result<(TokenStream, Functi
7574

7675
let result = #ident(#(#arg_accessors, )*);
7776

78-
#return_handler
77+
if let Err(e) = result.set_zval(retval, false) {
78+
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
79+
e.throw().expect("Failed to throw exception");
80+
}
7981
}
8082
};
8183

@@ -202,61 +204,6 @@ fn build_arg_accessors(args: &[Arg]) -> Vec<TokenStream> {
202204
args.iter().map(|arg| arg.get_accessor()).collect()
203205
}
204206

205-
pub fn build_return_handler(output_type: &ReturnType) -> TokenStream {
206-
let handler = match output_type {
207-
ReturnType::Default => Some(quote! { retval.set_null(); }),
208-
ReturnType::Type(_, ref ty) => match **ty {
209-
Type::Path(ref path) => match path.path.segments.last() {
210-
Some(path_seg) => match path_seg.ident.to_string().as_ref() {
211-
"Result" => Some(quote! {
212-
match result {
213-
Ok(result) => match result.set_zval(retval, false) {
214-
Ok(_) => {}
215-
Err(e) => {
216-
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
217-
e.throw().expect("Failed to throw exception: Failed to set return value.");
218-
},
219-
},
220-
Err(e) => {
221-
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
222-
e.throw().expect("Failed to throw exception: Error type returned from internal function.");
223-
}
224-
};
225-
}),
226-
"Option" => Some(quote! {
227-
match result {
228-
Some(result) => match result.set_zval(retval, false) {
229-
Ok(_) => {}
230-
Err(e) => {
231-
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
232-
e.throw().expect("Failed to throw exception: Failed to set return value.");
233-
},
234-
},
235-
None => retval.set_null(),
236-
};
237-
}),
238-
_ => None,
239-
},
240-
_ => None,
241-
},
242-
_ => None,
243-
},
244-
};
245-
246-
match handler {
247-
Some(handler) => handler,
248-
None => quote! {
249-
match result.set_zval(retval, false) {
250-
Ok(_) => {},
251-
Err(e) => {
252-
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
253-
e.throw().expect("Failed to throw exception: Failed to set return value.");
254-
}
255-
}
256-
},
257-
}
258-
}
259-
260207
pub fn get_return_type(output_type: &ReturnType) -> Result<Option<(String, bool)>> {
261208
Ok(match output_type {
262209
ReturnType::Default => None,

ext-php-rs-derive/src/method.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ pub fn parser(input: &mut ImplItemMethod, rename_rule: RenameRule) -> Result<Par
114114
let (arg_definitions, is_static) = build_arg_definitions(&args);
115115
let arg_parser = build_arg_parser(args.iter(), &optional)?;
116116
let arg_accessors = build_arg_accessors(&args);
117-
let return_handler = function::build_return_handler(output);
118117
let this = if is_static {
119118
quote! { Self:: }
120119
} else {
@@ -133,7 +132,10 @@ pub fn parser(input: &mut ImplItemMethod, rename_rule: RenameRule) -> Result<Par
133132

134133
let result = #this #ident(#(#arg_accessors, )*);
135134

136-
#return_handler
135+
if let Err(e) = result.set_zval(retval, false) {
136+
let e: ::ext_php_rs::php::exceptions::PhpException = e.into();
137+
e.throw().expect("Failed to throw exception");
138+
}
137139
}
138140
};
139141

guide/src/macros/structs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub struct RedisException;
7575

7676
// Throw our newly created exception
7777
#[php_function]
78-
pub fn throw_exception() -> Result<i32, PhpException<'static>> {
78+
pub fn throw_exception() -> PhpResult<i32> {
7979
Err(PhpException::from_class::<RedisException>("Not good!".into()))
8080
}
8181
# #[php_module]

src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl From<NulError> for Error {
9595
}
9696
}
9797

98-
impl<'a> From<Error> for PhpException<'a> {
98+
impl From<Error> for PhpException {
9999
fn from(err: Error) -> Self {
100100
Self::default(err.to_string())
101101
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ pub use ext_php_rs_derive::php_module;
398398
/// pub struct Example;
399399
///
400400
/// #[php_function]
401-
/// pub fn throw_exception() -> Result<i32, PhpException<'static>> {
401+
/// pub fn throw_exception() -> Result<i32, PhpException> {
402402
/// Err(PhpException::from_class::<Example>("Bad things happen".into()))
403403
/// }
404404
///
@@ -439,6 +439,7 @@ pub use ext_php_rs_derive::php_startup;
439439

440440
/// A module typically glob-imported containing the typically required macros and imports.
441441
pub mod prelude {
442+
pub use crate::php::exceptions::{PhpException, PhpResult};
442443
pub use crate::php::module::ModuleBuilder;
443444
pub use crate::php::types::callable::Callable;
444445
#[cfg(any(docs, feature = "closure"))]

src/php/exceptions.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
};
1616

1717
/// Result type with the error variant as a [`PhpException`].
18-
pub type PhpResult<T = ()> = std::result::Result<T, PhpException<'static>>;
18+
pub type PhpResult<T = ()> = std::result::Result<T, PhpException>;
1919

2020
/// Represents a PHP exception which can be thrown using the `throw()` function. Primarily used to
2121
/// return from a [`Result<T, PhpException>`] which can immediately be thrown by the `ext-php-rs`
@@ -25,21 +25,21 @@ pub type PhpResult<T = ()> = std::result::Result<T, PhpException<'static>>;
2525
/// can also be returned from these functions. You can also implement [`From<T>`] for your custom
2626
/// error type.
2727
#[derive(Debug)]
28-
pub struct PhpException<'a> {
28+
pub struct PhpException {
2929
message: String,
3030
code: i32,
31-
ex: &'a ClassEntry,
31+
ex: &'static ClassEntry,
3232
}
3333

34-
impl<'a> PhpException<'a> {
34+
impl PhpException {
3535
/// Creates a new exception instance.
3636
///
3737
/// # Parameters
3838
///
3939
/// * `message` - Message to contain in the exception.
4040
/// * `code` - Integer code to go inside the exception.
4141
/// * `ex` - Exception type to throw.
42-
pub fn new(message: String, code: i32, ex: &'a ClassEntry) -> Self {
42+
pub fn new(message: String, code: i32, ex: &'static ClassEntry) -> Self {
4343
Self { message, code, ex }
4444
}
4545

@@ -69,13 +69,13 @@ impl<'a> PhpException<'a> {
6969
}
7070
}
7171

72-
impl<'a> From<String> for PhpException<'a> {
72+
impl From<String> for PhpException {
7373
fn from(str: String) -> Self {
7474
Self::default(str)
7575
}
7676
}
7777

78-
impl<'a> From<&str> for PhpException<'a> {
78+
impl From<&str> for PhpException {
7979
fn from(str: &str) -> Self {
8080
Self::default(str.into())
8181
}

src/php/types/object.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::{
2626
php::{
2727
class::ClassEntry,
2828
enums::DataType,
29-
exceptions::PhpException,
29+
exceptions::PhpResult,
3030
flags::ZvalTypeFlags,
3131
types::{array::OwnedHashTable, string::ZendString},
3232
},
@@ -649,7 +649,7 @@ impl ZendObjectHandlers {
649649
type_: c_int,
650650
cache_slot: *mut *mut c_void,
651651
rv: *mut Zval,
652-
) -> std::result::Result<*mut Zval, PhpException<'static>> {
652+
) -> PhpResult<*mut Zval> {
653653
let obj = object
654654
.as_ref()
655655
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
@@ -696,7 +696,7 @@ impl ZendObjectHandlers {
696696
member: *mut zend_string,
697697
value: *mut Zval,
698698
cache_slot: *mut *mut c_void,
699-
) -> std::result::Result<*mut Zval, PhpException<'static>> {
699+
) -> PhpResult<*mut Zval> {
700700
let obj = object
701701
.as_ref()
702702
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
@@ -734,7 +734,7 @@ impl ZendObjectHandlers {
734734
unsafe fn internal<T: RegisteredClass>(
735735
object: *mut zend_object,
736736
props: &mut HashTable,
737-
) -> std::result::Result<(), PhpException<'static>> {
737+
) -> PhpResult {
738738
let obj = object
739739
.as_ref()
740740
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))
@@ -779,7 +779,7 @@ impl ZendObjectHandlers {
779779
member: *mut zend_string,
780780
has_set_exists: c_int,
781781
cache_slot: *mut *mut c_void,
782-
) -> std::result::Result<c_int, PhpException<'static>> {
782+
) -> PhpResult<c_int> {
783783
let obj = object
784784
.as_ref()
785785
.and_then(|obj| ZendClassObject::<T>::from_zend_obj_ptr(obj))

src/php/types/zval.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
zend_value, zval, zval_ptr_dtor,
1515
},
1616
errors::{Error, Result},
17-
php::pack::Pack,
17+
php::{exceptions::PhpException, pack::Pack},
1818
};
1919

2020
use crate::php::{
@@ -692,6 +692,24 @@ where
692692
}
693693
}
694694

695+
impl<T, E> IntoZval for std::result::Result<T, E>
696+
where
697+
T: IntoZval,
698+
E: Into<PhpException>,
699+
{
700+
const TYPE: DataType = T::TYPE;
701+
702+
fn set_zval(self, zv: &mut Zval, persistent: bool) -> Result<()> {
703+
match self {
704+
Ok(val) => val.set_zval(zv, persistent),
705+
Err(e) => {
706+
let ex: PhpException = e.into();
707+
ex.throw()
708+
}
709+
}
710+
}
711+
}
712+
695713
/// Allows zvals to be converted into Rust types in a fallible way. Reciprocal of the [`IntoZval`]
696714
/// trait.
697715
pub trait FromZval<'a>: Sized {

0 commit comments

Comments
 (0)