use std::fmt::Debug;
use allocative::Allocative;
use crate::typing::custom::TyCustom;
use crate::values::typing::type_compiled::alloc::TypeMatcherAlloc;
use crate::values::typing::type_compiled::type_matcher_factory::TypeMatcherFactory;
use crate::values::Value;
pub trait TypeMatcher: Allocative + Debug + Clone + Sized + Send + Sync + 'static {
fn matches(&self, value: Value) -> bool;
fn is_wildcard(&self) -> bool {
false
}
}
pub(crate) trait TypeMatcherDyn: Debug + Allocative + Send + Sync + 'static {
fn matches_dyn(&self, value: Value) -> bool;
fn is_wildcard_dyn(&self) -> bool;
fn to_box(&self) -> TypeMatcherBox;
}
impl<T: TypeMatcher> TypeMatcherDyn for T {
fn matches_dyn(&self, value: Value) -> bool {
TypeMatcher::matches(self, value)
}
fn is_wildcard_dyn(&self) -> bool {
TypeMatcher::is_wildcard(self)
}
fn to_box(&self) -> TypeMatcherBox {
TypeMatcherBox::new(self.clone())
}
}
#[derive(Debug, Allocative)]
pub(crate) struct TypeMatcherBox(pub(crate) Box<dyn TypeMatcherDyn>);
impl TypeMatcherBox {
pub(crate) fn new<T: TypeMatcher>(matcher: T) -> TypeMatcherBox {
TypeMatcherBox(Box::new(matcher))
}
}
impl Clone for TypeMatcherBox {
fn clone(&self) -> Self {
self.0.to_box()
}
}
impl TypeMatcher for TypeMatcherBox {
fn matches(&self, value: Value) -> bool {
self.0.matches_dyn(value)
}
fn is_wildcard(&self) -> bool {
self.0.is_wildcard_dyn()
}
}
pub(crate) struct TypeMatcherBoxAlloc;
impl TypeMatcherAlloc for TypeMatcherBoxAlloc {
type Result = TypeMatcherBox;
fn alloc<T: TypeMatcher>(self, matcher: T) -> Self::Result {
TypeMatcherBox::new(matcher)
}
fn custom(self, custom: &TyCustom) -> Self::Result {
custom.matcher_with_box()
}
fn from_type_matcher_factory(self, factory: &TypeMatcherFactory) -> Self::Result {
factory.factory.matcher_box()
}
}