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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use std::collections::HashMap;

use async_std::sync::Arc;

use crate::Error;

/// Container for storing specific services
///
/// Stores all services of the same type (trait, int, ...) into an HashMap container
/// wrapped within async Arc
pub struct Container<T> {
    services: HashMap<String, Arc<T>>,
}

impl<T> Container<T> {
    /// Creates a new Container
    ///
    /// ```
    /// use icee_container_rs::Container;
    ///
    /// let mut container = Container::<usize>::new();
    /// ```
    pub fn new() -> Self {
        Container {
            services: HashMap::new(),
        }
    }

    /// Checks whether or not a given field is registered
    ///
    /// ```
    /// use icee_container_rs::Container;
    ///
    /// let container = Container::<usize>::new();
    /// let exists = container.has("echo");
    /// # assert_eq!(exists, false);
    /// ```
    pub fn has(&self, name: &str) -> bool {
        self.services.contains_key(name)
    }

    /// Receives stored field from container
    ///
    /// ```
    /// use icee_container_rs::Container;
    ///
    /// let container = Container::<usize>::new();
    /// let value = container.get("echo");
    /// # assert_eq!(value.is_err(), true);
    /// ```
    pub fn get(&self, name: &str) -> Result<Arc<T>, Error> {
        if !self.has(name) {
            return Err(Error::NotFound(name.to_string()));
        }

        Ok(self.services.get(name).unwrap().clone())
    }

    /// Stores service into container and returns pointer
    ///
    /// ```
    /// use icee_container_rs::Container;
    /// use async_std::sync::Arc;
    ///
    /// let mut container = Container::<usize>::new();
    /// let srv: Arc<usize> = container.set("echo", 666);
    /// # assert_eq!(srv, Arc::new(666));
    /// ```
    pub fn set(&mut self, name: &str, service: T) -> Arc<T> {
        self.services.insert(String::from(name), Arc::new(service));
        self.get(name).unwrap()
    }

    /// List all available registered services
    ///
    /// ```
    /// use icee_container_rs::Container;
    ///
    /// let container = Container::<usize>::new();
    /// let names = container.list();
    /// ```
    pub fn list(&self) -> Vec<String> {
        self.services.keys().cloned().collect::<Vec<String>>()
    }
}

impl<T> Default for Container<T> {
    fn default() -> Self {
        Self::new()
    }
}