use std::sync::Arc;
use crate::container::Container;
use crate::types::SyncBounds;
pub trait Provider: 'static {
type Output: SyncBounds;
fn provide(&self, container: &Container) -> Self::Output;
}
impl<T: SyncBounds> Provider for Arc<T> {
type Output = Arc<T>;
fn provide(&self, _container: &Container) -> Self::Output {
Arc::clone(self)
}
}
pub struct CloneProvider<T>(T);
impl<T> CloneProvider<T> {
#[must_use]
pub fn new(value: T) -> Self {
Self(value)
}
}
impl<T> Provider for CloneProvider<T>
where
T: SyncBounds + Clone,
{
type Output = T;
fn provide(&self, _container: &Container) -> Self::Output {
self.0.clone()
}
}
#[must_use]
pub fn cloned<T>(value: T) -> CloneProvider<T>
where
T: SyncBounds + Clone,
{
CloneProvider::new(value)
}
pub struct CopyProvider<T>(T);
impl<T> CopyProvider<T> {
#[must_use]
pub fn new(value: T) -> Self {
Self(value)
}
}
impl<T> Provider for CopyProvider<T>
where
T: SyncBounds + Copy,
{
type Output = T;
fn provide(&self, _container: &Container) -> Self::Output {
self.0
}
}
#[must_use]
pub fn copied<T>(value: T) -> CopyProvider<T>
where
T: SyncBounds + Copy,
{
CopyProvider::new(value)
}
impl<T, F> Provider for F
where
T: SyncBounds,
F: Fn(&Container) -> T + SyncBounds,
{
type Output = T;
fn provide(&self, container: &Container) -> Self::Output {
self(container)
}
}