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
pub use self::ext::{Dependencies, Resolve};
mod ext;

use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::marker::PhantomData;
use std::sync::{Arc, Mutex};
use super::{Component, Construct, };

pub struct Graph<M>(Arc<Shared>, PhantomData<M>) where M: ?Sized;

type Dyn = Box<Any + 'static + Send>;
type Container = HashMap<TypeId, Dyn>;
type Shared = Mutex<Container>;

impl<M> Graph<M> where M: ?Sized {
    
    /// Constructs a new, empty `Graph<M>`.
    pub fn new() -> Graph<M> {
        
        let hash_map = HashMap::new();
        let mutex = Mutex::new(hash_map);
        let arc = Arc::new(mutex);
        
        return Graph(arc, PhantomData);
    }
    
    pub fn dep<T>(&self) -> <Graph<M> as Resolve<T, M::Scope>>::CoImp
        where M: Component<T>, 
              T: 'static + ?Sized, 
              Graph<M>: for<'imp> Resolve<'imp, T, M::Scope> {
        
        self.__resolve()
    }

    pub fn construct<'dep, I>(&'dep self) -> I
        where I: Construct<'dep>,
              Graph<M>: Dependencies<'dep, <I as Construct<'dep>>::Dep> {

        let deps = self.__dependencies();
        I::__construct(deps)
    }

//    /// Force a component to be created eagerly.
//    ///
//    /// By default, all components are created when needed (i.e., lazily). `eager` allows you to 
//    /// create a component at the beginning of an application.
//    ///
//    /// ## Example
//    ///
//    /// ```rust
//    /// // ..
//    /// ```
//    pub fn eager<T>(&self) -> !
//        where M: Component<T, Scope=Singleton>, 
//              T: 'static + ?Sized, Graph<M>: for<'imp> Resolve<'imp, T, M::Scope> {
//
//        unimplemented!()
//    }
}

impl<M> Clone for Graph<M> where M: ?Sized {
    
    fn clone(&self) -> Self {
        
        let &Graph(ref arc, ..) = self;
        
        Graph(arc.clone(), PhantomData)
    }
}