simpledi_rs/
macrorule.rs

1#[macro_export]
2macro_rules! create_dep {
3    ($obj:expr, $container:expr) => {{
4        $container.add($obj).unwrap()
5    }};
6
7    ($obj:expr, $container:expr, $($t:tt)+) => {{
8        $container.add($obj).unwrap()$($t)+
9    }};
10}
11
12#[macro_export]
13macro_rules! inject_dep {
14    ($struct:ident, $container:expr) => {{
15        unsafe {
16            let ptr = $container.get::<$struct>().unwrap() as *const dyn DependencyInjectTrait;
17            let ptr = ptr as *mut dyn DependencyInjectTrait;
18            let s = &mut *ptr;
19
20            s.inject($container);
21        }
22    }};
23}
24
25#[cfg(test)]
26mod tests {
27    use std::sync::Arc;
28
29    use crate::di::{DependencyInjectTrait, DIContainer, DIContainerTrait};
30
31    #[derive(Debug)]
32    struct DIStruct;
33
34    #[derive(Debug)]
35    struct DIAwareStruct(Option<Arc<DIContainer>>);
36
37    impl DIStruct {
38        fn new() -> Self {
39            Self {}
40        }
41    }
42
43    impl DIAwareStruct {
44        fn new() -> Self {
45            Self { 0: None }
46        }
47    }
48
49    impl DependencyInjectTrait for DIAwareStruct {
50        fn inject(&mut self, container: Arc<DIContainer>) {
51            self.0 = Some(container.clone())
52        }
53    }
54
55    #[test]
56    fn test_create_dep() {
57        let mut container = DIContainer::new();
58
59        // add obj to DI
60        let obj_ptr = {
61            let obj = create_dep!(DIStruct::new(), container);
62            obj as *const DIStruct
63        };
64
65        // get obj from DI
66        let container_arc = container.init().unwrap();
67        let injected_obj = container_arc.get::<DIStruct>().unwrap();
68
69        assert_eq!(obj_ptr, injected_obj as *const DIStruct);
70    }
71
72    #[test]
73    fn test_inject_dep() {
74        let mut container = DIContainer::new();
75
76        // add obj to DI
77        create_dep!(DIAwareStruct::new(), container);
78
79        // inject DI container to aware objects
80        let container_arc = container.init().unwrap();
81        let container_ptr = container_arc.as_ref() as *const DIContainer;
82
83        inject_dep!(DIAwareStruct, container_arc.clone());
84
85        // get container from aware objects
86        let injected_obj = container_arc.get::<DIAwareStruct>().unwrap();
87        let injected_container = injected_obj.0.as_ref().unwrap().as_ref();
88
89        assert_eq!(container_ptr, injected_container as *const DIContainer);
90    }
91}