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 #[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}