brisk_it/
generator.rs

1//! Traits and structure used for generating the imperative representation from the declartive representation.
2
3use std::collections::HashMap;
4
5/// Result type, which return a token stream with the error
6pub type Result<T> = std::result::Result<T, proc_macro2::TokenStream>;
7
8/// Implement this trait to convert a ComponentInput into its imperative form.
9pub trait Generator: Sync {
10    /// Generate the imperative form.
11    fn generate(
12        &self,
13        input: crate::component::ComponentInput,
14        manager: &Manager,
15    ) -> Result<proc_macro2::TokenStream>;
16    /// Clone this generator
17    fn boxed_clone(&self) -> Box<dyn Generator>;
18}
19
20/// A `Manager` contains a list of generator that can be used by `brisk_it` to generate the code.
21pub struct Manager {
22    generators: HashMap<String, Box<dyn Generator>>,
23}
24
25impl Manager {
26    /// Generate the given component
27    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
43/// Used to initialise a manager
44pub struct ManagerBuilder {
45    manager: Manager,
46}
47
48impl Default for ManagerBuilder {
49    fn default() -> Self {
50        Self::new()
51    }
52}
53
54impl ManagerBuilder {
55    /// Create an empty builder
56    pub fn new() -> Self {
57        Self {
58            manager: Manager {
59                generators: Default::default(),
60            },
61        }
62    }
63    /// Create a generator and add it to the builder
64    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    /// Add a generator to the builder
74    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    /// Clone the generators of an other manager, and insert them in this
84    /// manager.
85    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}