sdi/lib.rs
1#![crate_type = "proc-macro"]
2
3use std::collections::HashMap;
4use std::sync::Mutex;
5
6use lazy_static::lazy_static;
7use proc_macro::TokenStream;
8
9lazy_static! {
10 static ref MAP: Mutex<HashMap<String, String>> =
11 Mutex::new(HashMap::new());
12}
13
14/// Register an statically resolved service expression indexed by key.
15///
16/// ## Example
17///
18/// ```rust
19/// use sdi::{inject, provide};
20///
21/// #[derive(Debug, PartialEq)]
22/// struct A;
23///
24/// impl A {
25/// pub fn new() -> A { A }
26/// provide!(A <- A::new());
27/// }
28///
29/// assert_eq!(A::new(), inject!(A))
30/// ```
31/// Provide by inject is also ok.
32/// ```rust
33/// use sdi::{inject, provide};
34///
35/// #[derive(Debug, PartialEq)]
36/// struct A;
37/// provide!(A <- A);
38///
39/// #[derive(Debug, PartialEq)]
40/// struct B(A);
41///
42/// impl B {
43/// pub fn new(a:A) -> B { B(a) }
44/// provide!(B <- B::new(inject!(A)));
45/// }
46///
47/// assert_eq!(B::new(A), inject!(B))
48/// ```
49#[proc_macro]
50pub fn provide(attr: TokenStream) -> TokenStream {
51 let (key, expr) = {
52 let stringify = attr.to_string();
53 let split: Vec<String> = stringify
54 .split(" <- ")
55 .map(|str| str.to_owned())
56 .collect();
57
58 let err_msg = "Invalid provider syntax, consider: provide!(<key> <- <expr>)";
59 if split.len() != 2 {
60 panic!("{}", err_msg);
61 }
62
63 let key = split
64 .get(0)
65 .expect(err_msg)
66 .to_owned();
67 let expr = split
68 .get(1)
69 .expect(err_msg)
70 .to_owned();
71
72 (key, expr)
73 };
74
75 MAP.lock()
76 .unwrap()
77 .insert(key, expr);
78
79 TokenStream::new()
80}
81
82/// Get an statically resolved service expression by key
83///
84/// ## Example
85///
86/// ```rust
87/// use sdi::{inject, provide};
88///
89/// #[derive(Debug, PartialEq)]
90/// struct A;
91///
92/// impl A {
93/// pub fn new() -> A { A }
94/// provide!(A <- A::new());
95/// }
96///
97/// assert_eq!(A::new(), inject!(A))
98/// ```
99#[proc_macro]
100pub fn inject(attr: TokenStream) -> TokenStream {
101 let key = attr.to_string();
102 MAP.lock()
103 .unwrap()
104 .get(&key)
105 .expect(&format!("Unknown inject key: `{}`", key))
106 .parse()
107 .unwrap()
108}