use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Apis {
#[serde(rename = "api", default)]
pub apis: Vec<Api>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct Api {
#[serde(rename = "Cclass")]
pub class: String,
#[serde(rename = "Cgroup")]
pub group: String,
#[serde(rename = "Capiversion")]
pub api_version: Option<String>,
pub exclusive: Option<bool>,
pub condition: Option<String>,
#[serde(rename = "licenseSet")]
pub license_set: Option<String>,
pub changelog: Option<String>,
pub description: Option<String>,
pub files: Option<ApiFiles>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct ApiFiles {
#[serde(rename = "file", default)]
pub files: Vec<ApiFile>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct ApiFile {
pub name: String,
pub category: String,
pub attr: Option<String>,
pub condition: Option<String>,
pub version: Option<String>,
pub select: Option<String>,
pub src: Option<String>,
pub path: Option<String>,
pub language: Option<String>,
pub scope: Option<String>,
pub public: Option<bool>,
pub projectpath: Option<String>,
pub copy: Option<String>,
}
#[cfg(test)]
mod tests {
use crate::apis::{Api, ApiFile, ApiFiles, Apis};
#[test]
fn parse_apis() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<apis>
<api Cclass="CMSIS" Cgroup="RTOS2" Capiversion="2.1.3" exclusive="false"
condition="ARMCC6" licenseSet="all" changelog="Changelog.txt">
<description>CMSIS-RTOS2 API for real-time operating systems</description>
<files>
<file category="header" name="CMSIS/RTOS2/Include/cmsis_os2.h"/>
<file category="doc" name="CMSIS/RTOS2/Doc/index.html" public="true"/>
</files>
</api>
<api Cclass="Device" Cgroup="Startup"/>
</apis>"#;
let apis: Apis = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(apis.apis.len(), 2);
assert_eq!(
apis.apis[0],
Api {
class: "CMSIS".to_string(),
group: "RTOS2".to_string(),
api_version: Some("2.1.3".to_string()),
exclusive: Some(false),
condition: Some("ARMCC6".to_string()),
license_set: Some("all".to_string()),
changelog: Some("Changelog.txt".to_string()),
description: Some("CMSIS-RTOS2 API for real-time operating systems".to_string()),
files: Some(ApiFiles {
files: vec![
ApiFile {
name: "CMSIS/RTOS2/Include/cmsis_os2.h".to_string(),
category: "header".to_string(),
attr: None,
condition: None,
version: None,
select: None,
src: None,
path: None,
language: None,
scope: None,
public: None,
projectpath: None,
copy: None,
},
ApiFile {
name: "CMSIS/RTOS2/Doc/index.html".to_string(),
category: "doc".to_string(),
attr: None,
condition: None,
version: None,
select: None,
src: None,
path: None,
language: None,
scope: None,
public: Some(true),
projectpath: None,
copy: None,
},
],
}),
}
);
assert_eq!(
apis.apis[1],
Api {
class: "Device".to_string(),
group: "Startup".to_string(),
api_version: None,
exclusive: None,
condition: None,
license_set: None,
changelog: None,
description: None,
files: None,
}
);
}
#[test]
fn parse_api_minimal() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<apis>
<api Cclass="Security" Cgroup="mbed TLS"/>
</apis>"#;
let apis: Apis = serde_roxmltree::from_str(xml_str).unwrap();
assert_eq!(apis.apis.len(), 1);
let api = &apis.apis[0];
assert_eq!(api.class, "Security");
assert_eq!(api.group, "mbed TLS");
assert_eq!(api.api_version, None);
assert_eq!(api.exclusive, None);
assert_eq!(api.condition, None);
assert_eq!(api.license_set, None);
assert_eq!(api.changelog, None);
assert_eq!(api.description, None);
assert_eq!(api.files, None);
}
#[test]
fn parse_api_files() {
let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
<apis>
<api Cclass="USB" Cgroup="Core">
<files>
<file category="header" name="USB/Include/usb_core.h"
condition="USB_Cond" version="1.0.0" attr="config"
select="USB Core Header" src="USB/Src/usb_core.c"
public="false"/>
</files>
</api>
</apis>"#;
let apis: Apis = serde_roxmltree::from_str(xml_str).unwrap();
let api = &apis.apis[0];
assert_eq!(api.class, "USB");
assert_eq!(api.group, "Core");
assert_eq!(api.description, None);
let files = api.files.as_ref().unwrap();
assert_eq!(files.files.len(), 1);
let file = &files.files[0];
assert_eq!(file.name, "USB/Include/usb_core.h");
assert_eq!(file.category, "header");
assert_eq!(file.condition, Some("USB_Cond".to_string()));
assert_eq!(file.version, Some("1.0.0".to_string()));
assert_eq!(file.attr, Some("config".to_string()));
assert_eq!(file.select, Some("USB Core Header".to_string()));
assert_eq!(file.src, Some("USB/Src/usb_core.c".to_string()));
assert_eq!(file.public, Some(false));
assert_eq!(file.path, None);
assert_eq!(file.language, None);
assert_eq!(file.scope, None);
assert_eq!(file.projectpath, None);
}
}