Struct ext_php_rs::closure::Closure
source · pub struct Closure(_);
closure
only.Expand description
Wrapper around a Rust closure, which can be exported to PHP.
Closures can have up to 8 parameters, all must implement FromZval
, and
can return anything that implements IntoZval
. Closures must have a
static lifetime, and therefore cannot modify any self
references.
Internally, closures are implemented as a PHP class. A class RustClosure
is registered with an __invoke
method:
<?php
class RustClosure {
public function __invoke(...$args): mixed {
// ...
}
}
The Rust closure is then double boxed, firstly as a Box<dyn Fn(...) -> ...>
(depending on the signature of the closure) and then finally boxed as
a Box<dyn PhpClosure>
. This is a workaround, as PhpClosure
is not
generically implementable on types that implement Fn(T, ...) -> Ret
. Make
a suggestion issue if you have a better idea of implementing this!.
When the __invoke
method is called from PHP, the invoke
method is called
on the dyn PhpClosure
\ trait object, and from there everything is
basically the same as a regular PHP function.
Implementations§
source§impl Closure
impl Closure
sourcepub fn wrap<T>(func: T) -> Selfwhere
T: PhpClosure + 'static,
pub fn wrap<T>(func: T) -> Selfwhere
T: PhpClosure + 'static,
Wraps a Fn
or FnMut
Rust closure into a type which can be
returned to PHP.
The closure can accept up to 8 arguments which implement IntoZval
,
and can return any type which implements FromZval
. The closure
must have a static lifetime, so cannot reference self
.
Parameters
func
- The closure to wrap. Should be boxed in the formBox<dyn Fn[Mut](...) -> ...>
.
Example
use ext_php_rs::closure::Closure;
let closure = Closure::wrap(Box::new(|name| {
format!("Hello {}", name)
}) as Box<dyn Fn(String) -> String>);
Examples found in repository?
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
fn into_closure(self) -> Closure {
let mut this = Some(self);
Closure::wrap(Box::new(move || {
let this = match this.take() {
Some(this) => this,
None => {
let _ = PhpException::default(
"Attempted to call `FnOnce` closure more than once.".into(),
)
.throw();
return Option::<R>::None;
}
};
Some(this())
}) as Box<dyn FnMut() -> Option<R>>)
}
sourcepub fn wrap_once<T>(func: T) -> Selfwhere
T: PhpOnceClosure + 'static,
pub fn wrap_once<T>(func: T) -> Selfwhere
T: PhpOnceClosure + 'static,
Wraps a FnOnce
Rust closure into a type which can be returned to
PHP. If the closure is called more than once from PHP, an exception
is thrown.
The closure can accept up to 8 arguments which implement IntoZval
,
and can return any type which implements FromZval
. The closure
must have a static lifetime, so cannot reference self
.
Parameters
func
- The closure to wrap. Should be boxed in the formBox<dyn FnOnce(...) -> ...>
.
Example
use ext_php_rs::closure::Closure;
let name: String = "Hello world".into();
let closure = Closure::wrap_once(Box::new(|| {
name
}) as Box<dyn FnOnce() -> String>);
Trait Implementations§
source§impl<'a> FromZendObject<'a> for &'a Closure
impl<'a> FromZendObject<'a> for &'a Closure
source§fn from_zend_object(obj: &'a ZendObject) -> Result<Self>
fn from_zend_object(obj: &'a ZendObject) -> Result<Self>
Self
from the source ZendObject
.source§impl<'a> FromZendObjectMut<'a> for &'a mut Closure
impl<'a> FromZendObjectMut<'a> for &'a mut Closure
source§fn from_zend_object_mut(obj: &'a mut ZendObject) -> Result<Self>
fn from_zend_object_mut(obj: &'a mut ZendObject) -> Result<Self>
Self
from the source ZendObject
.source§impl<'a> FromZvalMut<'a> for &'a mut Closure
impl<'a> FromZvalMut<'a> for &'a mut Closure
source§impl IntoZendObject for Closure
impl IntoZendObject for Closure
source§fn into_zend_object(self) -> Result<ZBox<ZendObject>>
fn into_zend_object(self) -> Result<ZBox<ZendObject>>
self
into a Zend object.