1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::{marker::PhantomData, sync::Arc};
use crate::{Catalog, InjectionError};
pub trait DependencySpec {
    type ReturnType;
    fn get(cat: &Catalog) -> Result<Self::ReturnType, InjectionError>;
}
pub struct OneOf<Iface>
where
    Iface: 'static + ?Sized + Send + Sync,
{
    _dummy: PhantomData<Iface>,
}
impl<Iface> DependencySpec for OneOf<Iface>
where
    Iface: 'static + ?Sized + Send + Sync,
{
    type ReturnType = Arc<Iface>;
    default fn get(cat: &Catalog) -> Result<Self::ReturnType, InjectionError> {
        let mut builders = cat.builders_for::<Iface>();
        if let Some(first) = builders.next() {
            if builders.next().is_some() {
                Err(InjectionError::ambiguous::<Iface>())
            } else {
                first.get(cat)
            }
        } else {
            Err(InjectionError::unregistered::<Iface>())
        }
    }
}
impl DependencySpec for OneOf<Catalog> {
    fn get(cat: &Catalog) -> Result<Self::ReturnType, InjectionError> {
        Ok(Arc::new(cat.clone()))
    }
}
pub struct AllOf<Iface>
where
    Iface: 'static + ?Sized,
{
    _dummy: PhantomData<Iface>,
}
impl<Iface> DependencySpec for AllOf<Iface>
where
    Iface: 'static + ?Sized,
{
    type ReturnType = Vec<Arc<Iface>>;
    fn get(cat: &Catalog) -> Result<Self::ReturnType, InjectionError> {
        cat.builders_for::<Iface>().map(|b| b.get(cat)).collect()
    }
}