1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
6pub struct Taxonomy {
10 #[serde(rename = "description", default)]
12 pub descriptions: Vec<TaxonomyDescription>,
13}
14
15#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
16pub struct TaxonomyDescription {
20 #[serde(rename = "Cclass")]
22 pub class: String,
23
24 #[serde(rename = "Cgroup")]
26 pub group: Option<String>,
27
28 pub doc: Option<String>,
30
31 pub generator: Option<String>,
33
34 pub public: Option<bool>,
36
37 pub condition: Option<String>,
39
40 #[serde(rename = "#content")]
42 pub content: String,
43}
44
45#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
46pub enum CclassType {
49 Audio,
50 BoardSupport,
51 BoardPart,
52 Compiler,
53 Cmsis,
55 CmsisDriver,
57 Device,
58 DataExchange,
59 ExtensionBoard,
60 FileSystem,
61 Graphics,
62 IotClient,
64 IotUtility,
66 Network,
67 Rtos,
69 Security,
70 Usb,
72 Utility,
73}
74
75impl TryFrom<&str> for CclassType {
76 type Error = ();
77 fn try_from(s: &str) -> Result<Self, Self::Error> {
78 match s {
79 "Audio" => Ok(Self::Audio),
80 "Board Support" => Ok(Self::BoardSupport),
81 "Board Part" => Ok(Self::BoardPart),
82 "Compiler" => Ok(Self::Compiler),
83 "CMSIS" => Ok(Self::Cmsis),
84 "CMSIS Driver" => Ok(Self::CmsisDriver),
85 "Device" => Ok(Self::Device),
86 "Data Exchange" => Ok(Self::DataExchange),
87 "Extension Board" => Ok(Self::ExtensionBoard),
88 "File System" => Ok(Self::FileSystem),
89 "Graphics" => Ok(Self::Graphics),
90 "IoT Client" => Ok(Self::IotClient),
91 "IoT Utility" => Ok(Self::IotUtility),
92 "Network" => Ok(Self::Network),
93 "RTOS" => Ok(Self::Rtos),
94 "Security" => Ok(Self::Security),
95 "USB" => Ok(Self::Usb),
96 "Utility" => Ok(Self::Utility),
97 _ => Err(()),
98 }
99 }
100}
101
102impl TryFrom<String> for CclassType {
103 type Error = ();
104 fn try_from(s: String) -> Result<Self, Self::Error> {
105 Self::try_from(s.as_str())
106 }
107}
108
109#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
110pub enum CgroupType {
113 Core,
115 Dsp,
117 NnLib,
119 Rtos,
121 Rtos2,
123 Startup,
124}
125
126impl TryFrom<&str> for CgroupType {
127 type Error = ();
128 fn try_from(s: &str) -> Result<Self, Self::Error> {
129 match s {
130 "CORE" => Ok(Self::Core),
131 "DSP" => Ok(Self::Dsp),
132 "NN Lib" => Ok(Self::NnLib),
133 "RTOS" => Ok(Self::Rtos),
134 "RTOS2" => Ok(Self::Rtos2),
135 "Startup" => Ok(Self::Startup),
136 _ => Err(()),
137 }
138 }
139}
140
141impl TryFrom<String> for CgroupType {
142 type Error = ();
143 fn try_from(s: String) -> Result<Self, Self::Error> {
144 Self::try_from(s.as_str())
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use crate::taxonomy::{Taxonomy, TaxonomyDescription};
151
152 #[test]
153 fn parse_taxonomy() {
154 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
155<taxonomy>
156 <description Cclass="Device" Cgroup="Startup" doc="Device/Doc/startup.htm"
157 generator="MyGen" public="true" condition="MyCondition">ARM Cortex-M device startup</description>
158 <description Cclass="Board Support"/>
159</taxonomy>"#;
160
161 let taxonomy: Taxonomy = serde_roxmltree::from_str(xml_str).unwrap();
162 assert_eq!(taxonomy.descriptions.len(), 2);
163
164 assert_eq!(
165 taxonomy.descriptions[0],
166 TaxonomyDescription {
167 class: "Device".to_string(),
168 group: Some("Startup".to_string()),
169 doc: Some("Device/Doc/startup.htm".to_string()),
170 generator: Some("MyGen".to_string()),
171 public: Some(true),
172 condition: Some("MyCondition".to_string()),
173 content: "ARM Cortex-M device startup".to_string(),
174 }
175 );
176 assert_eq!(
177 taxonomy.descriptions[1],
178 TaxonomyDescription {
179 class: "Board Support".to_string(),
180 group: None,
181 doc: None,
182 generator: None,
183 public: None,
184 condition: None,
185 content: "".to_string(),
186 }
187 );
188 }
189
190 #[test]
191 fn parse_taxonomy_minimal() {
192 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
193<taxonomy>
194 <description Cclass="CMSIS"/>
195</taxonomy>"#;
196
197 let taxonomy: Taxonomy = serde_roxmltree::from_str(xml_str).unwrap();
198 assert_eq!(taxonomy.descriptions.len(), 1);
199
200 let desc = &taxonomy.descriptions[0];
201 assert_eq!(desc.class, "CMSIS");
202 assert_eq!(desc.group, None);
203 assert_eq!(desc.doc, None);
204 assert_eq!(desc.generator, None);
205 assert_eq!(desc.public, None);
206 assert_eq!(desc.content, "");
207 }
208
209 #[test]
210 fn parse_taxonomy_content() {
211 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
212<taxonomy>
213 <description Cclass="Compiler">ARM Compiler software components</description>
214</taxonomy>"#;
215
216 let taxonomy: Taxonomy = serde_roxmltree::from_str(xml_str).unwrap();
217 let desc = &taxonomy.descriptions[0];
218
219 assert_eq!(desc.class, "Compiler");
220 assert_eq!(desc.group, None);
221 assert_eq!(desc.content, "ARM Compiler software components");
222 }
223
224 #[test]
225 fn cclass_type_try_from() {
226 use crate::taxonomy::CclassType;
227
228 assert_eq!(CclassType::try_from("Audio"), Ok(CclassType::Audio));
229 assert_eq!(CclassType::try_from("CMSIS"), Ok(CclassType::Cmsis));
230 assert_eq!(
231 CclassType::try_from("CMSIS Driver"),
232 Ok(CclassType::CmsisDriver)
233 );
234 assert_eq!(CclassType::try_from("RTOS"), Ok(CclassType::Rtos));
235 assert_eq!(CclassType::try_from("USB"), Ok(CclassType::Usb));
236 assert_eq!(
237 CclassType::try_from("IoT Client"),
238 Ok(CclassType::IotClient)
239 );
240 assert_eq!(CclassType::try_from("Unknown Class"), Err(()));
241
242 let s = "Board Support".to_string();
243 assert_eq!(CclassType::try_from(s), Ok(CclassType::BoardSupport));
244 }
245
246 #[test]
247 fn cgroup_type_try_from() {
248 use crate::taxonomy::CgroupType;
249
250 assert_eq!(CgroupType::try_from("CORE"), Ok(CgroupType::Core));
251 assert_eq!(CgroupType::try_from("DSP"), Ok(CgroupType::Dsp));
252 assert_eq!(CgroupType::try_from("NN Lib"), Ok(CgroupType::NnLib));
253 assert_eq!(CgroupType::try_from("RTOS"), Ok(CgroupType::Rtos));
254 assert_eq!(CgroupType::try_from("RTOS2"), Ok(CgroupType::Rtos2));
255 assert_eq!(CgroupType::try_from("Startup"), Ok(CgroupType::Startup));
256 assert_eq!(CgroupType::try_from("Unknown Group"), Err(()));
257
258 let s = "NN Lib".to_string();
259 assert_eq!(CgroupType::try_from(s), Ok(CgroupType::NnLib));
260 }
261}