use crate::ModelIden;
use crate::resolver::Result;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub enum ModelMapper {
MapperFn(Arc<Box<dyn ModelMapperFn>>),
}
impl ModelMapper {
pub fn from_mapper_fn(mapper_fn: impl IntoModelMapperFn) -> Self {
ModelMapper::MapperFn(mapper_fn.into_mapper_fn())
}
}
impl ModelMapper {
pub(crate) fn map_model(&self, model_iden: ModelIden) -> Result<ModelIden> {
match self {
ModelMapper::MapperFn(mapper_fn) => {
mapper_fn.clone().exec_fn(model_iden)
}
}
}
}
pub trait ModelMapperFn: Send + Sync {
fn exec_fn(&self, model_iden: ModelIden) -> Result<ModelIden>;
fn clone_box(&self) -> Box<dyn ModelMapperFn>;
}
impl<F> ModelMapperFn for F
where
F: FnOnce(ModelIden) -> Result<ModelIden> + Send + Sync + Clone + 'static,
{
fn exec_fn(&self, model_iden: ModelIden) -> Result<ModelIden> {
(self.clone())(model_iden)
}
fn clone_box(&self) -> Box<dyn ModelMapperFn> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn ModelMapperFn> {
fn clone(&self) -> Box<dyn ModelMapperFn> {
self.clone_box()
}
}
impl std::fmt::Debug for dyn ModelMapperFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ModelMapperFn")
}
}
pub trait IntoModelMapperFn {
fn into_mapper_fn(self) -> Arc<Box<dyn ModelMapperFn>>;
}
impl IntoModelMapperFn for Arc<Box<dyn ModelMapperFn>> {
fn into_mapper_fn(self) -> Arc<Box<dyn ModelMapperFn>> {
self
}
}
impl<F> IntoModelMapperFn for F
where
F: FnOnce(ModelIden) -> Result<ModelIden> + Send + Sync + Clone + 'static,
{
fn into_mapper_fn(self) -> Arc<Box<dyn ModelMapperFn>> {
Arc::new(Box::new(self))
}
}