Struct ext_php_rs::builders::FunctionBuilder
source · pub struct FunctionBuilder<'a> { /* private fields */ }
Expand description
Builder for registering a function in PHP.
Implementations§
source§impl<'a> FunctionBuilder<'a>
impl<'a> FunctionBuilder<'a>
sourcepub fn new<T: Into<String>>(
name: T,
handler: extern "C" fn(execute_data: &mut ExecuteData, retval: &mut Zval)
) -> Self
pub fn new<T: Into<String>>(
name: T,
handler: extern "C" fn(execute_data: &mut ExecuteData, retval: &mut Zval)
) -> Self
Creates a new function builder, used to build functions to be exported to PHP.
Parameters
name
- The name of the function.handler
- The handler to be called when the function is invoked from PHP.
Examples found in repository?
More examples
src/closure.rs (line 127)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
pub fn build() {
if CLOSURE_META.has_ce() {
panic!("Closure has already been built.");
}
let ce = ClassBuilder::new("RustClosure")
.method(
FunctionBuilder::new("__invoke", Self::invoke)
.not_required()
.arg(Arg::new("args", DataType::Mixed).is_variadic())
.returns(DataType::Mixed, false, true)
.build()
.expect("Failed to build `RustClosure` PHP class."),
MethodFlags::Public,
)
.object_override::<Self>()
.build()
.expect("Failed to build `RustClosure` PHP class.");
CLOSURE_META.set_ce(ce);
}
src/builders/class.rs (line 213)
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
pub fn object_override<T: RegisteredClass>(mut self) -> Self {
extern "C" fn create_object<T: RegisteredClass>(_: *mut ClassEntry) -> *mut ZendObject {
// SAFETY: After calling this function, PHP will always call the constructor
// defined below, which assumes that the object is uninitialized.
let obj = unsafe { ZendClassObject::<T>::new_uninit() };
obj.into_raw().get_mut_zend_obj()
}
zend_fastcall! {
extern fn constructor<T: RegisteredClass>(ex: &mut ExecuteData, _: &mut Zval) {
let ConstructorMeta { constructor, .. } = match T::CONSTRUCTOR {
Some(c) => c,
None => {
PhpException::default("You cannot instantiate this class from PHP.".into())
.throw()
.expect("Failed to throw exception when constructing class");
return;
}
};
let this = match constructor(ex) {
ConstructorResult::Ok(this) => this,
ConstructorResult::Exception(e) => {
e.throw()
.expect("Failed to throw exception while constructing class");
return;
}
ConstructorResult::ArgError => return,
};
let this_obj = match ex.get_object::<T>() {
Some(obj) => obj,
None => {
PhpException::default("Failed to retrieve reference to `this` object.".into())
.throw()
.expect("Failed to throw exception while constructing class");
return;
}
};
this_obj.initialize(this);
}
}
debug_assert_eq!(
self.name.as_str(),
T::CLASS_NAME,
"Class name in builder does not match class name in `impl RegisteredClass`."
);
self.object_override = Some(create_object::<T>);
self.method(
{
let mut func = FunctionBuilder::new("__construct", constructor::<T>);
if let Some(ConstructorMeta { build_fn, .. }) = T::CONSTRUCTOR {
func = build_fn(func);
}
func.build().expect("Failed to build constructor function")
},
MethodFlags::Public,
)
}
sourcepub fn new_abstract<T: Into<String>>(name: T) -> Self
pub fn new_abstract<T: Into<String>>(name: T) -> Self
Create a new function builder for an abstract function that can be used on an abstract class or an interface.
Parameters
name
- The name of the function.
sourcepub fn constructor(
handler: extern "C" fn(execute_data: &mut ExecuteData, retval: &mut Zval)
) -> Self
pub fn constructor(
handler: extern "C" fn(execute_data: &mut ExecuteData, retval: &mut Zval)
) -> Self
Creates a constructor builder, used to build the constructor for classes.
Parameters
handler
- The handler to be called when the function is invoked from PHP.
sourcepub fn arg(self, arg: Arg<'a>) -> Self
pub fn arg(self, arg: Arg<'a>) -> Self
Examples found in repository?
src/closure.rs (line 129)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
pub fn build() {
if CLOSURE_META.has_ce() {
panic!("Closure has already been built.");
}
let ce = ClassBuilder::new("RustClosure")
.method(
FunctionBuilder::new("__invoke", Self::invoke)
.not_required()
.arg(Arg::new("args", DataType::Mixed).is_variadic())
.returns(DataType::Mixed, false, true)
.build()
.expect("Failed to build `RustClosure` PHP class."),
MethodFlags::Public,
)
.object_override::<Self>()
.build()
.expect("Failed to build `RustClosure` PHP class.");
CLOSURE_META.set_ce(ce);
}
sourcepub fn not_required(self) -> Self
pub fn not_required(self) -> Self
Sets the rest of the given arguments as not required.
Examples found in repository?
src/closure.rs (line 128)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
pub fn build() {
if CLOSURE_META.has_ce() {
panic!("Closure has already been built.");
}
let ce = ClassBuilder::new("RustClosure")
.method(
FunctionBuilder::new("__invoke", Self::invoke)
.not_required()
.arg(Arg::new("args", DataType::Mixed).is_variadic())
.returns(DataType::Mixed, false, true)
.build()
.expect("Failed to build `RustClosure` PHP class."),
MethodFlags::Public,
)
.object_override::<Self>()
.build()
.expect("Failed to build `RustClosure` PHP class.");
CLOSURE_META.set_ce(ce);
}
sourcepub fn returns(self, type_: DataType, as_ref: bool, allow_null: bool) -> Self
pub fn returns(self, type_: DataType, as_ref: bool, allow_null: bool) -> Self
Sets the return value of the function.
Parameters
type_
- The return type of the function.as_ref
- Whether the function returns a reference.allow_null
- Whether the function return value is nullable.
Examples found in repository?
src/closure.rs (line 130)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
pub fn build() {
if CLOSURE_META.has_ce() {
panic!("Closure has already been built.");
}
let ce = ClassBuilder::new("RustClosure")
.method(
FunctionBuilder::new("__invoke", Self::invoke)
.not_required()
.arg(Arg::new("args", DataType::Mixed).is_variadic())
.returns(DataType::Mixed, false, true)
.build()
.expect("Failed to build `RustClosure` PHP class."),
MethodFlags::Public,
)
.object_override::<Self>()
.build()
.expect("Failed to build `RustClosure` PHP class.");
CLOSURE_META.set_ce(ce);
}
sourcepub fn build(self) -> Result<FunctionEntry>
pub fn build(self) -> Result<FunctionEntry>
Builds the function converting it into a Zend function entry.
Returns a result containing the function entry if successful.
Examples found in repository?
src/closure.rs (line 131)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
pub fn build() {
if CLOSURE_META.has_ce() {
panic!("Closure has already been built.");
}
let ce = ClassBuilder::new("RustClosure")
.method(
FunctionBuilder::new("__invoke", Self::invoke)
.not_required()
.arg(Arg::new("args", DataType::Mixed).is_variadic())
.returns(DataType::Mixed, false, true)
.build()
.expect("Failed to build `RustClosure` PHP class."),
MethodFlags::Public,
)
.object_override::<Self>()
.build()
.expect("Failed to build `RustClosure` PHP class.");
CLOSURE_META.set_ce(ce);
}
More examples
src/builders/class.rs (line 217)
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
pub fn object_override<T: RegisteredClass>(mut self) -> Self {
extern "C" fn create_object<T: RegisteredClass>(_: *mut ClassEntry) -> *mut ZendObject {
// SAFETY: After calling this function, PHP will always call the constructor
// defined below, which assumes that the object is uninitialized.
let obj = unsafe { ZendClassObject::<T>::new_uninit() };
obj.into_raw().get_mut_zend_obj()
}
zend_fastcall! {
extern fn constructor<T: RegisteredClass>(ex: &mut ExecuteData, _: &mut Zval) {
let ConstructorMeta { constructor, .. } = match T::CONSTRUCTOR {
Some(c) => c,
None => {
PhpException::default("You cannot instantiate this class from PHP.".into())
.throw()
.expect("Failed to throw exception when constructing class");
return;
}
};
let this = match constructor(ex) {
ConstructorResult::Ok(this) => this,
ConstructorResult::Exception(e) => {
e.throw()
.expect("Failed to throw exception while constructing class");
return;
}
ConstructorResult::ArgError => return,
};
let this_obj = match ex.get_object::<T>() {
Some(obj) => obj,
None => {
PhpException::default("Failed to retrieve reference to `this` object.".into())
.throw()
.expect("Failed to throw exception while constructing class");
return;
}
};
this_obj.initialize(this);
}
}
debug_assert_eq!(
self.name.as_str(),
T::CLASS_NAME,
"Class name in builder does not match class name in `impl RegisteredClass`."
);
self.object_override = Some(create_object::<T>);
self.method(
{
let mut func = FunctionBuilder::new("__construct", constructor::<T>);
if let Some(ConstructorMeta { build_fn, .. }) = T::CONSTRUCTOR {
func = build_fn(func);
}
func.build().expect("Failed to build constructor function")
},
MethodFlags::Public,
)
}