use serde::{Deserialize, Serialize};
use crate::family::Family;
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
pub struct Description {
pub overview: Option<String>,
#[serde(rename = "#content")]
pub content: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Eccn {
#[serde(rename = "ECCN-EU")]
pub eu: String,
#[serde(rename = "ECCN-US")]
pub us: String,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct LicenseSets {
#[serde(rename = "licenseSet")]
pub license_set: Vec<LicenseSet>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct LicenseSet {
pub id: String,
pub default: Option<bool>,
pub gating: Option<bool>,
pub license: Vec<License>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct License {
pub name: String,
pub title: String,
pub spdx: Option<String>,
pub url: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Dominate {
pub info: String,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Repository {
#[serde(rename = "type")]
pub repository_type: Option<String>,
#[serde(rename = "#content")]
pub url: String,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
pub struct Releases {
pub release: Vec<Release>,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
pub struct Release {
pub version: String,
pub date: Option<String>,
pub tag: Option<String>,
pub url: Option<String>,
pub deprecated: Option<String>,
pub replacement: Option<String>,
#[serde(rename = "#content")]
pub content: String,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Changelogs {
pub changelog: Vec<Changelog>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Changelog {
pub id: String,
pub name: String,
pub default: Option<bool>,
#[serde(rename = "type")]
pub changelog_type: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Keywords {
#[serde(rename = "keyword")]
pub keywords: Vec<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Environments {
#[serde(rename = "environment")]
pub environments: Vec<Environment>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Environment {
pub name: String,
#[serde(rename = "Pname")]
pub processor_name: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
pub struct Devices<'a> {
#[serde(rename = "family", default)]
#[serde(borrow)]
pub families: Vec<Family<'a>>,
}
#[cfg(test)]
mod tests {
use std::default;
use crate::pdsc::{
Changelogs, Devices, Eccn, License, LicenseSet, Release, Releases, Repository,
};
#[test]
fn parse_eccn() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<ECCN>
<ECCN-EU>NEC</ECCN-EU>
<ECCN-US>5D992.c</ECCN-US>
</ECCN>"#;
let eccn: Eccn = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(eccn.eu, "NEC".to_string());
assert_eq!(eccn.us, "5D992.c".to_string());
}
#[test]
fn parse_eccn_missing_field() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<ECCN>
<ECCN-US>5D992.c</ECCN-US>
</ECCN>"#;
let eccn: Result<Eccn, _> = serde_roxmltree::from_str(xml_str);
assert!(eccn.is_err());
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<ECCN>
<ECCN-EU>NEC</ECCN-EU>
</ECCN>"#;
let eccn: Result<Eccn, _> = serde_roxmltree::from_str(xml_str);
assert!(eccn.is_err());
}
#[test]
fn parse_license_set() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<licenseSet id="all" default="true" gating="false">
<license name="LICENSE.txt"
title="Apache License, Version 2.0"
spdx="Apache-2.0"
url="https://www.apache.org/licenses/LICENSE-2.0"/>
</licenseSet>"#;
let license_set: LicenseSet = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(
license_set,
LicenseSet {
id: "all".to_string(),
default: Some(true),
gating: Some(false),
license: vec![License {
name: "LICENSE.txt".to_string(),
title: "Apache License, Version 2.0".to_string(),
spdx: Some("Apache-2.0".to_string()),
url: Some("https://www.apache.org/licenses/LICENSE-2.0".to_string())
}]
}
);
}
#[test]
fn parse_repository() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<repository type="git">https://github.com/ARM-software/CMSIS-Driver.git</repository>"#;
let repo: Repository = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(repo.repository_type, Some("git".to_string()));
assert_eq!(
repo.url,
"https://github.com/ARM-software/CMSIS-Driver.git".to_string()
);
}
#[test]
fn parse_releases() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<releases>
<release version="1.1.1" date="2020-05-12">Fixed a problem with the feature xyz.</release>
<release version="1.1.0" date="2020-03-13">Introduces a new feature xyz.</release>
<release version="1.0.0" date="2020-02-23">First published version.</release>
</releases>
"#;
let releases: Releases = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(
releases,
Releases {
release: vec![
Release {
version: "1.1.1".to_string(),
date: Some("2020-05-12".to_string()),
content: "Fixed a problem with the feature xyz.".to_string(),
..default::Default::default()
},
Release {
version: "1.1.0".to_string(),
date: Some("2020-03-13".to_string()),
content: "Introduces a new feature xyz.".to_string(),
..default::Default::default()
},
Release {
version: "1.0.0".to_string(),
date: Some("2020-02-23".to_string()),
content: "First published version.".to_string(),
..default::Default::default()
},
]
}
);
}
#[test]
fn parse_releases_public_repo() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<releases>
<release version="2.1.0" tag="2.1.0" url="https://github.com/ARM-software/CMSIS-Driver/archive/2.1.0.zip">
Added LAN9220 Ethernet MAC+PHY driver.
</release>
<release version="2.0.0" tag="2.0.0" url="https://github.com/ARM-software/CMSIS-Driver/archive/2.0.0.zip">
First published version.
</release>
</releases>"#;
let releases: Releases = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(
releases,
Releases {
release: vec![
Release {
version: "2.1.0".to_string(),
tag: Some("2.1.0".to_string()),
url: Some(
"https://github.com/ARM-software/CMSIS-Driver/archive/2.1.0.zip"
.to_string()
),
content: "\n Added LAN9220 Ethernet MAC+PHY driver.\n ".to_string(),
..default::Default::default()
},
Release {
version: "2.0.0".to_string(),
tag: Some("2.0.0".to_string()),
url: Some(
"https://github.com/ARM-software/CMSIS-Driver/archive/2.0.0.zip"
.to_string()
),
content: "\n First published version.\n ".to_string(),
..default::Default::default()
},
]
}
);
}
#[test]
fn parse_releases_deprecated() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<releases>
<release version="1.0.1" date="2020-04-18" deprecated="2020-04-18" replacement="Vendor.pack_name">
</release>
<release version="1.0.0" date="2020-03-24">Initial version.
</release>
</releases>"#;
let releases: Releases = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(
releases,
Releases {
release: vec![
Release {
version: "1.0.1".to_string(),
date: Some("2020-04-18".to_string()),
deprecated: Some("2020-04-18".to_string()),
replacement: Some("Vendor.pack_name".to_string()),
content: "\n ".to_string(),
..default::Default::default()
},
Release {
version: "1.0.0".to_string(),
date: Some("2020-03-24".to_string()),
content: "Initial version.\n ".to_string(),
..default::Default::default()
},
]
}
);
}
#[test]
fn parse_devices_multiple_families() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<devices>
<family Dfamily="FamilyA" Dvendor="ARM:82">
<debugvars configfile="a.dbgconf" version="1.0.0"></debugvars>
<sequences/>
</family>
<family Dfamily="FamilyB" Dvendor="ARM:82">
<debugvars configfile="b.dbgconf" version="2.0.0"></debugvars>
<sequences/>
</family>
</devices>"#;
let document = roxmltree::Document::parse(xml_str).unwrap();
let devices: Devices = serde_roxmltree::from_doc(&document).unwrap();
assert_eq!(devices.families.len(), 2);
assert_eq!(devices.families[0].device_family, "FamilyA");
assert_eq!(devices.families[1].device_family, "FamilyB");
}
#[test]
fn parse_changelog_default_bool() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<changelogs>
<changelog id="all" name="CHANGELOG.md" default="true"/>
<changelog id="other" name="OTHER.md"/>
</changelogs>"#;
let changelogs: Changelogs = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(changelogs.changelog.len(), 2);
assert_eq!(changelogs.changelog[0].id, "all");
assert_eq!(changelogs.changelog[0].name, "CHANGELOG.md");
assert_eq!(changelogs.changelog[0].default, Some(true));
assert_eq!(changelogs.changelog[1].id, "other");
assert_eq!(changelogs.changelog[1].default, None);
}
}