use std::{any::TypeId, marker::PhantomData};
use crate::{
builders::FunctionBuilder,
class::{ClassEntryInfo, ConstructorMeta, RegisteredClass},
convert::{IntoZval, IntoZvalDyn},
describe::DocComments,
flags::{ConstantFlags, MethodFlags},
internal::property::PropertyDescriptor,
};
pub struct InterfaceRegistration {
pub class_type_id: TypeId,
pub interface_getter: fn() -> ClassEntryInfo,
}
inventory::collect!(InterfaceRegistration);
pub trait InterfaceMethodsProvider<T: RegisteredClass> {
fn get_interface_methods(self) -> Vec<(FunctionBuilder<'static>, MethodFlags)>;
}
impl<T: RegisteredClass> InterfaceMethodsProvider<T> for &'_ PhpClassImplCollector<T> {
#[inline]
fn get_interface_methods(self) -> Vec<(FunctionBuilder<'static>, MethodFlags)> {
Vec::new()
}
}
pub struct PhpClassImplCollector<T: RegisteredClass>(PhantomData<T>);
impl<T: RegisteredClass> Default for PhpClassImplCollector<T> {
#[inline]
fn default() -> Self {
Self(PhantomData)
}
}
pub trait PhpClassImpl<T: RegisteredClass> {
fn get_methods(self) -> Vec<(FunctionBuilder<'static>, MethodFlags)>;
fn get_method_props(self) -> &'static [PropertyDescriptor<T>];
fn get_constructor(self) -> Option<ConstructorMeta<T>>;
fn get_constants(
self,
) -> &'static [(
&'static str,
&'static dyn IntoZvalDyn,
DocComments,
ConstantFlags,
)];
}
impl<T: RegisteredClass> PhpClassImpl<T> for &'_ PhpClassImplCollector<T> {
#[inline]
fn get_methods(self) -> Vec<(FunctionBuilder<'static>, MethodFlags)> {
Vec::default()
}
#[inline]
fn get_method_props(self) -> &'static [PropertyDescriptor<T>] {
&[]
}
#[inline]
fn get_constructor(self) -> Option<ConstructorMeta<T>> {
Option::default()
}
#[inline]
fn get_constants(
self,
) -> &'static [(
&'static str,
&'static dyn IntoZvalDyn,
DocComments,
ConstantFlags,
)] {
&[]
}
}
pub struct DefaultProbe<T>(PhantomData<T>);
impl<T> Default for DefaultProbe<T> {
fn default() -> Self {
Self(PhantomData)
}
}
pub trait ProbeDefault<T> {
fn default_init(self) -> Option<T>;
}
impl<T: Default> ProbeDefault<T> for DefaultProbe<T> {
#[inline]
fn default_init(self) -> Option<T> {
Some(T::default())
}
}
impl<T> ProbeDefault<T> for &'_ DefaultProbe<T> {
#[inline]
fn default_init(self) -> Option<T> {
None
}
}
pub struct CloneProbe<T>(PhantomData<T>);
impl<T> Default for CloneProbe<T> {
fn default() -> Self {
Self(PhantomData)
}
}
pub trait ProbeClone<T> {
fn clone_obj(self, value: &T) -> Option<T>;
}
impl<T: Clone> ProbeClone<T> for CloneProbe<T> {
#[inline]
fn clone_obj(self, value: &T) -> Option<T> {
Some(value.clone())
}
}
impl<T> ProbeClone<T> for &'_ CloneProbe<T> {
#[inline]
fn clone_obj(self, _: &T) -> Option<T> {
None
}
}
impl<T: RegisteredClass + IntoZval> IntoZval for PhpClassImplCollector<T> {
const TYPE: crate::flags::DataType = T::TYPE;
const NULLABLE: bool = T::NULLABLE;
#[inline]
fn set_zval(self, _: &mut crate::types::Zval, _: bool) -> crate::error::Result<()> {
unreachable!();
}
}