Skip to main content

esp_generate/
template.rs

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