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),
37 )
38 .to_compile_error())
39 }
40 }
41}
42
43pub struct ManagerBuilder {
45 manager: Manager,
46}
47
48impl Default for ManagerBuilder {
49 fn default() -> Self {
50 Self::new()
51 }
52}
53
54impl ManagerBuilder {
55 pub fn new() -> Self {
57 Self {
58 manager: Manager {
59 generators: Default::default(),
60 },
61 }
62 }
63 pub fn create<T>(mut self, name: impl Into<String>) -> Self
65 where
66 T: Generator + 'static + Default,
67 {
68 self.manager
69 .generators
70 .insert(name.into(), Box::new(T::default()));
71 self
72 }
73 pub fn add<T>(mut self, name: impl Into<String>, generator: T) -> Self
75 where
76 T: Generator + 'static,
77 {
78 self.manager
79 .generators
80 .insert(name.into(), Box::new(generator));
81 self
82 }
83 pub fn insert(mut self, manager: &Manager) -> Self {
86 for (k, v) in manager.generators.iter() {
87 self.manager
88 .generators
89 .insert(k.to_owned(), v.boxed_clone());
90 }
91 self
92 }
93}
94
95impl From<ManagerBuilder> for Manager {
96 fn from(val: ManagerBuilder) -> Self {
97 val.manager
98 }
99}