use super::Container;
use super::factory::{BoxedFactory, Factory};
use crate::error::Result;
pub trait Resolver<Container> {
type Return;
fn resolve(&self, registry: &Container) -> Result<Self::Return>;
}
pub trait CloneResolver<Container>: Resolver<Container> {
fn clone_box(&self) -> Box<dyn CloneResolver<Container, Return = Self::Return> + Send + Sync>;
}
impl<R, T> CloneResolver<R> for T
where
T: Resolver<R> + Send + Sync + Clone + 'static,
{
fn clone_box(&self) -> Box<dyn CloneResolver<R, Return = T::Return> + Send + Sync> {
Box::new(self.clone())
}
}
pub struct BoxedResolver<R, T>(Box<dyn CloneResolver<R, Return = T> + Send + Sync>);
impl<R, T> Clone for BoxedResolver<R, T> {
fn clone(&self) -> Self {
Self(self.0.clone_box())
}
}
impl<R, T> BoxedResolver<R, T> {
pub fn new<I>(resolver: I) -> Self
where
I: Resolver<R, Return = T> + Clone + Send + Sync + 'static,
{
Self(Box::new(resolver))
}
}
impl<R, T> Resolver<R> for BoxedResolver<R, T> {
type Return = T;
fn resolve(&self, registry: &R) -> Result<T> {
self.0.resolve(registry)
}
}
impl<F, T, Deps, C> Resolver<C> for BoxedFactory<F, T, Deps>
where
F: Factory<T, Deps> + Clone + Send + Sync + 'static,
T: 'static,
Deps: 'static,
C: Container,
{
type Return = T;
fn resolve(&self, registry: &C) -> Result<T> {
let factory = self.factory.clone();
Factory::create(factory, registry)
}
}