use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Taxonomy {
#[serde(rename = "description", default)]
pub descriptions: Vec<TaxonomyDescription>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct TaxonomyDescription {
#[serde(rename = "Cclass")]
pub class: String,
#[serde(rename = "Cgroup")]
pub group: Option<String>,
pub doc: Option<String>,
pub generator: Option<String>,
pub public: Option<bool>,
pub condition: Option<String>,
#[serde(rename = "#content")]
pub content: String,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
pub enum CclassType {
Audio,
BoardSupport,
BoardPart,
Compiler,
Cmsis,
CmsisDriver,
Device,
DataExchange,
ExtensionBoard,
FileSystem,
Graphics,
IotClient,
IotUtility,
Network,
Rtos,
Security,
Usb,
Utility,
}
impl TryFrom<&str> for CclassType {
type Error = ();
fn try_from(s: &str) -> Result<Self, Self::Error> {
match s {
"Audio" => Ok(Self::Audio),
"Board Support" => Ok(Self::BoardSupport),
"Board Part" => Ok(Self::BoardPart),
"Compiler" => Ok(Self::Compiler),
"CMSIS" => Ok(Self::Cmsis),
"CMSIS Driver" => Ok(Self::CmsisDriver),
"Device" => Ok(Self::Device),
"Data Exchange" => Ok(Self::DataExchange),
"Extension Board" => Ok(Self::ExtensionBoard),
"File System" => Ok(Self::FileSystem),
"Graphics" => Ok(Self::Graphics),
"IoT Client" => Ok(Self::IotClient),
"IoT Utility" => Ok(Self::IotUtility),
"Network" => Ok(Self::Network),
"RTOS" => Ok(Self::Rtos),
"Security" => Ok(Self::Security),
"USB" => Ok(Self::Usb),
"Utility" => Ok(Self::Utility),
_ => Err(()),
}
}
}
impl TryFrom<String> for CclassType {
type Error = ();
fn try_from(s: String) -> Result<Self, Self::Error> {
Self::try_from(s.as_str())
}
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
pub enum CgroupType {
Core,
Dsp,
NnLib,
Rtos,
Rtos2,
Startup,
}
impl TryFrom<&str> for CgroupType {
type Error = ();
fn try_from(s: &str) -> Result<Self, Self::Error> {
match s {
"CORE" => Ok(Self::Core),
"DSP" => Ok(Self::Dsp),
"NN Lib" => Ok(Self::NnLib),
"RTOS" => Ok(Self::Rtos),
"RTOS2" => Ok(Self::Rtos2),
"Startup" => Ok(Self::Startup),
_ => Err(()),
}
}
}
impl TryFrom<String> for CgroupType {
type Error = ();
fn try_from(s: String) -> Result<Self, Self::Error> {
Self::try_from(s.as_str())
}
}
#[cfg(test)]
mod tests {
use crate::taxonomy::{Taxonomy, TaxonomyDescription};
#[test]
fn parse_taxonomy() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<taxonomy>
<description Cclass="Device" Cgroup="Startup" doc="Device/Doc/startup.htm"
generator="MyGen" public="true" condition="MyCondition">ARM Cortex-M device startup</description>
<description Cclass="Board Support"/>
</taxonomy>"#;
let taxonomy: Taxonomy = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(taxonomy.descriptions.len(), 2);
assert_eq!(
taxonomy.descriptions[0],
TaxonomyDescription {
class: "Device".to_string(),
group: Some("Startup".to_string()),
doc: Some("Device/Doc/startup.htm".to_string()),
generator: Some("MyGen".to_string()),
public: Some(true),
condition: Some("MyCondition".to_string()),
content: "ARM Cortex-M device startup".to_string(),
}
);
assert_eq!(
taxonomy.descriptions[1],
TaxonomyDescription {
class: "Board Support".to_string(),
group: None,
doc: None,
generator: None,
public: None,
condition: None,
content: "".to_string(),
}
);
}
#[test]
fn parse_taxonomy_minimal() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<taxonomy>
<description Cclass="CMSIS"/>
</taxonomy>"#;
let taxonomy: Taxonomy = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(taxonomy.descriptions.len(), 1);
let desc = &taxonomy.descriptions[0];
assert_eq!(desc.class, "CMSIS");
assert_eq!(desc.group, None);
assert_eq!(desc.doc, None);
assert_eq!(desc.generator, None);
assert_eq!(desc.public, None);
assert_eq!(desc.content, "");
}
#[test]
fn parse_taxonomy_content() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<taxonomy>
<description Cclass="Compiler">ARM Compiler software components</description>
</taxonomy>"#;
let taxonomy: Taxonomy = serde_roxmltree::from_str(xml_str).unwrap();
let desc = &taxonomy.descriptions[0];
assert_eq!(desc.class, "Compiler");
assert_eq!(desc.group, None);
assert_eq!(desc.content, "ARM Compiler software components");
}
#[test]
fn cclass_type_try_from() {
use crate::taxonomy::CclassType;
assert_eq!(CclassType::try_from("Audio"), Ok(CclassType::Audio));
assert_eq!(CclassType::try_from("CMSIS"), Ok(CclassType::Cmsis));
assert_eq!(
CclassType::try_from("CMSIS Driver"),
Ok(CclassType::CmsisDriver)
);
assert_eq!(CclassType::try_from("RTOS"), Ok(CclassType::Rtos));
assert_eq!(CclassType::try_from("USB"), Ok(CclassType::Usb));
assert_eq!(
CclassType::try_from("IoT Client"),
Ok(CclassType::IotClient)
);
assert_eq!(CclassType::try_from("Unknown Class"), Err(()));
let s = "Board Support".to_string();
assert_eq!(CclassType::try_from(s), Ok(CclassType::BoardSupport));
}
#[test]
fn cgroup_type_try_from() {
use crate::taxonomy::CgroupType;
assert_eq!(CgroupType::try_from("CORE"), Ok(CgroupType::Core));
assert_eq!(CgroupType::try_from("DSP"), Ok(CgroupType::Dsp));
assert_eq!(CgroupType::try_from("NN Lib"), Ok(CgroupType::NnLib));
assert_eq!(CgroupType::try_from("RTOS"), Ok(CgroupType::Rtos));
assert_eq!(CgroupType::try_from("RTOS2"), Ok(CgroupType::Rtos2));
assert_eq!(CgroupType::try_from("Startup"), Ok(CgroupType::Startup));
assert_eq!(CgroupType::try_from("Unknown Group"), Err(()));
let s = "NN Lib".to_string();
assert_eq!(CgroupType::try_from(s), Ok(CgroupType::NnLib));
}
}