Struct ext_php_rs::builders::ClassBuilder
source · pub struct ClassBuilder { /* private fields */ }
Expand description
Builder for registering a class in PHP.
Implementations§
source§impl ClassBuilder
impl ClassBuilder
sourcepub fn new<T: Into<String>>(name: T) -> Self
pub fn new<T: Into<String>>(name: T) -> Self
Creates a new class builder, used to build classes to be exported to PHP.
Parameters
name
- The name of the class.
Examples found in repository?
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 extends(self, parent: &'static ClassEntry) -> Self
pub fn extends(self, parent: &'static ClassEntry) -> Self
sourcepub fn implements(self, interface: &'static ClassEntry) -> Self
pub fn implements(self, interface: &'static ClassEntry) -> Self
Implements an interface on the class.
Parameters
interface
- Interface to implement on the class.
Panics
Panics when the given class entry interface
is not an interface.
sourcepub fn method(self, func: FunctionEntry, flags: MethodFlags) -> Self
pub fn method(self, func: FunctionEntry, flags: MethodFlags) -> Self
Adds a method to the class.
Parameters
func
- The function entry to add to the class.flags
- Flags relating to the function. SeeMethodFlags
.
Examples found in repository?
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
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 property<T: Into<String>>(
self,
name: T,
default: impl IntoZval,
flags: PropertyFlags
) -> Self
pub fn property<T: Into<String>>(
self,
name: T,
default: impl IntoZval,
flags: PropertyFlags
) -> Self
Adds a property to the class. The initial type of the property is given by the type of the given default. Note that the user can change the type.
Parameters
name
- The name of the property to add to the class.default
- The default value of the property.flags
- Flags relating to the property. SeePropertyFlags
.
Panics
Function will panic if the given default
cannot be converted into a
Zval
.
sourcepub fn constant<T: Into<String>>(
self,
name: T,
value: impl IntoZval
) -> Result<Self>
pub fn constant<T: Into<String>>(
self,
name: T,
value: impl IntoZval
) -> Result<Self>
Adds a constant to the class. The type of the constant is defined by the type of the given default.
Returns a result containing the class builder if the constant was successfully added.
Parameters
name
- The name of the constant to add to the class.value
- The value of the constant.
sourcepub fn flags(self, flags: ClassFlags) -> Self
pub fn flags(self, flags: ClassFlags) -> Self
sourcepub fn object_override<T: RegisteredClass>(self) -> Self
pub fn object_override<T: RegisteredClass>(self) -> Self
Overrides the creation of the Zend object which will represent an instance of this class.
Parameters
T
- The type which will override the Zend object. Must implementRegisteredClass
which can be derived using thephp_class
attribute macro.
Panics
Panics if the class name associated with T
is not the same as the
class name specified when creating the builder.
Examples found in repository?
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<&'static mut ClassEntry>
pub fn build(self) -> Result<&'static mut ClassEntry>
Builds the class, returning a reference to the class entry.
Errors
Returns an Error
variant if the class could not be registered.
Examples found in repository?
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);
}