1use std::collections::HashMap;
4
5pub type Result<T> = std::result::Result<T, proc_macro2::TokenStream>;
7
8pub trait Generator: Sync {
10 fn generate(
12 &self,
13 input: crate::component::ComponentInput,
14 manager: &Manager,
15 ) -> Result<proc_macro2::TokenStream>;
16 fn boxed_clone(&self) -> Box<dyn Generator>;
18}
19
20pub struct Manager {
22 generators: HashMap<String, Box<dyn Generator>>,
23}
24
25impl Manager {
26 pub fn generate(
28 &self,
29 input: crate::component::ComponentInput,
30 ) -> Result<proc_macro2::TokenStream> {
31 if let Some(generator) = self.generators.get(&input.name.to_string()) {
32 generator.generate(input, self)
33 } else {
34 Err(syn::Error::new(
35 input.name.span(),
36 format!("No generator for component: {}", input.name.to_string()),
37 )
38 .to_compile_error()
39 .into())
40 }
41 }
42}
43
44pub struct ManagerBuilder {
46 manager: Manager,
47}
48
49impl ManagerBuilder {
50 pub fn new() -> Self {
52 Self {
53 manager: Manager {
54 generators: Default::default(),
55 },
56 }
57 }
58 pub fn create<T>(mut self, name: impl Into<String>) -> Self
60 where
61 T: Generator + 'static + Default,
62 {
63 self.manager
64 .generators
65 .insert(name.into(), Box::new(T::default()));
66 self
67 }
68 pub fn add<T>(mut self, name: impl Into<String>, generator: T) -> Self
70 where
71 T: Generator + 'static,
72 {
73 self.manager
74 .generators
75 .insert(name.into(), Box::new(generator));
76 self
77 }
78 pub fn insert(mut self, manager: &Manager) -> Self {
80 for (k, v) in manager.generators.iter() {
81 self.manager
82 .generators
83 .insert(k.to_owned(), v.boxed_clone());
84 }
85 self
86 }
87}
88
89impl Into<Manager> for ManagerBuilder {
90 fn into(self) -> Manager {
91 self.manager
92 }
93}