use std::{ops::Deref, sync::Arc};
use crate::Result;
#[derive(Debug)]
pub struct Inject<T: Send + Sync + 'static>(Arc<T>);
impl<T: Send + Sync + 'static> Inject<T> {
pub fn new(value: Arc<T>) -> Self {
Self(value)
}
pub fn into_inner(self) -> Arc<T> {
self.0
}
}
impl<T: Send + Sync + 'static> Clone for Inject<T> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}
impl<T: Send + Sync + 'static> Deref for Inject<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
#[derive(Clone, Debug)]
pub struct Optional<T: Send + Sync + 'static>(Option<Inject<T>>);
impl<T: Send + Sync + 'static> Optional<T> {
pub fn new(value: Option<Inject<T>>) -> Self {
Self(value)
}
pub fn is_some(&self) -> bool {
self.0.is_some()
}
pub fn is_none(&self) -> bool {
self.0.is_none()
}
pub fn as_ref(&self) -> Option<&Inject<T>> {
self.0.as_ref()
}
pub fn into_option(self) -> Option<Inject<T>> {
self.0
}
}
#[derive(Clone)]
pub struct Lazy<T: Send + Sync + 'static> {
resolver: Arc<dyn Fn() -> Result<Inject<T>> + Send + Sync>,
}
impl<T: Send + Sync + 'static> Lazy<T> {
pub fn new(resolver: impl Fn() -> Result<Inject<T>> + Send + Sync + 'static) -> Self {
Self {
resolver: Arc::new(resolver),
}
}
pub fn get(&self) -> Result<Inject<T>> {
(self.resolver)()
}
}
#[derive(Clone)]
pub struct Factory<T: Send + Sync + 'static> {
factory: Arc<dyn Fn() -> Result<T> + Send + Sync>,
}
impl<T: Send + Sync + 'static> Factory<T> {
pub fn new(factory: impl Fn() -> Result<T> + Send + Sync + 'static) -> Self {
Self {
factory: Arc::new(factory),
}
}
pub fn create(&self) -> Result<T> {
(self.factory)()
}
}
#[derive(Clone, Debug)]
pub struct Scoped<T: Send + Sync + 'static>(Inject<T>);
impl<T: Send + Sync + 'static> Scoped<T> {
pub fn new(value: Inject<T>) -> Self {
Self(value)
}
pub fn into_inject(self) -> Inject<T> {
self.0
}
}
impl<T: Send + Sync + 'static> Deref for Scoped<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}