esp_generate/
template.rs

1use esp_metadata::Chip;
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Serialize, Deserialize, Debug)]
5pub struct GeneratorOption {
6    pub name: String,
7    pub display_name: String,
8    /// Selecting one option in the group deselect other options of the same group.
9    #[serde(default)]
10    pub selection_group: String,
11    #[serde(default)]
12    pub help: String,
13    #[serde(default)]
14    pub requires: Vec<String>,
15    #[serde(default)]
16    pub chips: Vec<Chip>,
17}
18
19impl GeneratorOption {
20    pub fn options(&self) -> Vec<String> {
21        vec![self.name.to_string()]
22    }
23}
24
25#[derive(Clone, Serialize, Deserialize, Debug)]
26pub struct GeneratorOptionCategory {
27    pub name: String,
28    pub display_name: String,
29    #[serde(default)]
30    pub help: String,
31    #[serde(default)]
32    pub requires: Vec<String>,
33    #[serde(default)]
34    pub options: Vec<GeneratorOptionItem>,
35}
36
37impl GeneratorOptionCategory {
38    pub fn options(&self) -> Vec<String> {
39        let mut res = Vec::new();
40        for option in self.options.iter() {
41            res.extend(option.options());
42        }
43        res
44    }
45}
46
47#[derive(Clone, Serialize, Deserialize, Debug)]
48pub enum GeneratorOptionItem {
49    Category(GeneratorOptionCategory),
50    Option(GeneratorOption),
51}
52
53impl GeneratorOptionItem {
54    pub fn title(&self) -> &str {
55        match self {
56            GeneratorOptionItem::Category(category) => category.display_name.as_str(),
57            GeneratorOptionItem::Option(option) => option.display_name.as_str(),
58        }
59    }
60
61    pub fn name(&self) -> &str {
62        match self {
63            GeneratorOptionItem::Category(category) => category.name.as_str(),
64            GeneratorOptionItem::Option(option) => option.name.as_str(),
65        }
66    }
67
68    pub fn options(&self) -> Vec<String> {
69        match self {
70            GeneratorOptionItem::Category(category) => category.options(),
71            GeneratorOptionItem::Option(option) => option.options(),
72        }
73    }
74
75    pub fn is_category(&self) -> bool {
76        matches!(self, GeneratorOptionItem::Category(_))
77    }
78
79    pub fn chips(&self) -> &[Chip] {
80        match self {
81            GeneratorOptionItem::Category(_) => &[],
82            GeneratorOptionItem::Option(option) => option.chips.as_slice(),
83        }
84    }
85
86    pub fn requires(&self) -> &[String] {
87        match self {
88            GeneratorOptionItem::Category(category) => category.requires.as_slice(),
89            GeneratorOptionItem::Option(option) => option.requires.as_slice(),
90        }
91    }
92
93    pub fn help(&self) -> &str {
94        match self {
95            GeneratorOptionItem::Category(category) => &category.help,
96            GeneratorOptionItem::Option(option) => &option.help,
97        }
98    }
99}
100
101#[derive(Clone, Serialize, Deserialize)]
102pub struct Template {
103    pub options: Vec<GeneratorOptionItem>,
104}
105
106impl Template {
107    pub fn all_options(&self) -> Vec<&GeneratorOption> {
108        all_options_in(&self.options)
109    }
110}
111
112fn all_options_in(options: &[GeneratorOptionItem]) -> Vec<&GeneratorOption> {
113    options
114        .iter()
115        .flat_map(|o| match o {
116            GeneratorOptionItem::Option(option) => vec![option],
117            GeneratorOptionItem::Category(category) => all_options_in(&category.options),
118        })
119        .collect()
120}