cmsis_pack/pack_index/
mod.rs1use crate::utils::prelude::*;
2use anyhow::Error;
3use roxmltree::Node;
4
5#[derive(Debug, Clone)]
6pub struct PdscRef {
7 pub url: String,
8 pub vendor: String,
9 pub name: String,
10 pub version: String,
11 pub date: Option<String>,
12 pub deprecated: Option<String>,
13 pub replacement: Option<String>,
14 pub size: Option<String>,
15}
16
17#[derive(Debug)]
18pub struct Pidx {
19 pub url: String,
20 pub vendor: String,
21 pub date: Option<String>,
22}
23
24#[derive(Debug)]
25pub struct Vidx {
26 pub vendor: String,
27 pub url: String,
28 pub timestamp: Option<String>,
29 pub pdsc_index: Vec<PdscRef>,
30 pub vendor_index: Vec<Pidx>,
31}
32
33impl FromElem for PdscRef {
34 fn from_elem(e: &Node) -> Result<Self, Error> {
35 assert_root_name(e, "pdsc")?;
36 Ok(Self {
37 url: attr_map(e, "url")?,
38 vendor: attr_map(e, "vendor")?,
39 name: attr_map(e, "name")?,
40 version: attr_map(e, "version")?,
41 date: attr_map(e, "date").ok(),
42 deprecated: attr_map(e, "deprecated").ok(),
43 replacement: attr_map(e, "replacement").ok(),
44 size: attr_map(e, "size").ok(),
45 })
46 }
47}
48
49impl FromElem for Pidx {
50 fn from_elem(e: &Node) -> Result<Self, Error> {
51 assert_root_name(e, "pidx")?;
52 Ok(Self {
53 url: attr_map(e, "url")?,
54 vendor: attr_map(e, "vendor")?,
55 date: attr_map(e, "date").ok(),
56 })
57 }
58}
59
60impl FromElem for Vidx {
61 fn from_elem(root: &Node) -> Result<Self, Error> {
62 assert_root_name(root, "index")?;
63 let vendor = child_text(root, "vendor")?;
64 let url = child_text(root, "url")?;
65
66 let mut timestamp: Option<String> = None;
67 let mut vendor_index: Vec<Pidx> = Vec::new();
68 let mut pdsc_index: Vec<PdscRef> = Vec::new();
69 for child in root.children() {
70 match child.tag_name().name() {
71 "timestamp" => {
72 timestamp = Some(child).map(|e| e.text().unwrap_or_default().to_string())
73 }
74 "vindex" => {
75 vendor_index = Pidx::vec_from_children(child.children());
76 }
77 "pindex" => {
78 pdsc_index = PdscRef::vec_from_children(child.children());
79 }
80 _ => continue,
81 }
82 }
83
84 Ok(Vidx {
85 vendor,
86 url,
87 timestamp,
88 vendor_index,
89 pdsc_index,
90 })
91 }
92}
93
94#[cfg(test)]
95mod test {
96 use super::*;
97
98 #[test]
99 fn pdscref_missing_attr() {
100 let erroring_strings = vec![
101 "<pdsc>",
102 "<pdsc url=\"Vendor\" name=\"Name\" version=\"1.2.3-alpha\">",
103 "<pdsc vendor=\"Vendor\" url=\"Url\" version=\"1.2.3-alpha\">",
104 "<pdsc vendor=\"Vendor\" name=\"Name\" url=\"Url\">",
105 "<pdsc vendor=\"Vendor\" name=\"Name\" version=\"1.2.3-alpha\">",
106 ];
107 for bad_string in erroring_strings {
108 assert!(PdscRef::from_string(bad_string).is_err());
109 }
110 }
111
112 #[test]
113 fn pdscref_wrong_elem() {
114 let bad_string =
115 "<notPdsc vendor=\"Vendor\" url=\"Url\" name=\"name\" version=\"1.2.3-alpha\">";
116 assert!(PdscRef::from_string(bad_string).is_err())
117 }
118
119 #[test]
120 fn pdscref_optionals() {
121 let good_string =
122 "<pdsc vendor=\"Vendor\" url=\"Url\" name=\"Name\" version=\"1.2.3-alpha\">";
123 let response = PdscRef::from_string(good_string).unwrap();
124 assert_eq!(response.vendor, String::from("Vendor"));
125 assert_eq!(response.url, "Url");
126 assert_eq!(response.name, String::from("Name"));
127 assert_eq!(response.version, String::from("1.2.3-alpha"));
128 let good_string =
129 "<pdsc vendor=\"Vendor\" url=\"Url\" name=\"Name\" version=\"1.2.3-alpha\"
130 date=\"A-Date\" deprecated=\"true\" replacement=\"Other\" size=\"8MB\">";
131 let response = PdscRef::from_string(good_string).unwrap();
132 assert_eq!(response.date, Some(String::from("A-Date")));
133 assert_eq!(response.deprecated, Some(String::from("true")));
134 assert_eq!(response.replacement, Some(String::from("Other")));
135 assert_eq!(response.size, Some(String::from("8MB")));
136 }
137
138 #[test]
139 fn pidx_misssing_attr() {
140 let erroring_strings = vec![
141 "<pidx/>",
142 "<pidx vendor=\"Vendor\"/>",
143 "<pidx url=\"Url\"/>",
144 ];
145 for bad_string in erroring_strings {
146 assert!(Pidx::from_string(bad_string).is_err());
147 }
148 }
149
150 #[test]
151 fn pidx_wrong_elem() {
152 let bad_string = "<notpidx url=\"Url\" vendor=\"Vendor\"/>";
153 assert!(Pidx::from_string(bad_string).is_err())
154 }
155
156 #[test]
157 fn pidx_optionals() {
158 let good_string = "<pidx vendor=\"Vendor\" url=\"Url\"/>";
159 let response = Pidx::from_string(good_string).unwrap();
160 assert_eq!(response.vendor, String::from("Vendor"));
161 assert_eq!(response.url, "Url");
162
163 let good_string =
164 "<pidx vendor=\"Vendor\" url=\"Url\" date=\"Fri Sep 1 11:21:06 CDT 2017\"/>";
165 let response = Pidx::from_string(good_string).unwrap();
166 assert_eq!(response.vendor, String::from("Vendor"));
167 assert_eq!(response.url, "Url");
168 assert_eq!(
169 response.date,
170 Some(String::from("Fri Sep 1 11:21:06 CDT 2017"))
171 )
172 }
173
174 #[test]
175 fn vidx_misssing_attr() {
176 let erroring_strings = vec![
177 "<index xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\">
178 </index>",
179 "<index xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\">
180 <vendor>Vendor</vendor>
181 </index>",
182 "<index xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\">
183 <url>Url</url>
184 </index>",
185 ];
186 for bad_string in erroring_strings {
187 assert!(Vidx::from_string(bad_string).is_err());
188 }
189 }
190
191 #[test]
192 fn vidx_wrong_elem() {
193 let bad_string = "<notindex xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\">
194 <vendor>Vendor</vendor>
195 <url>Url</url>
196 </notindex>";
197 assert!(Vidx::from_string(bad_string).is_err())
198 }
199
200 #[test]
201 fn vidx_optionals() {
202 let good_string = "<index xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\">
203 <vendor>Vendor</vendor>
204 <url>Url</url>
205 </index>";
206 let response = Vidx::from_string(good_string).unwrap();
207 assert_eq!(response.vendor, String::from("Vendor"));
208 assert_eq!(response.url, "Url");
209
210 let good_string = "<index xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\">
211 <vendor>Vendor</vendor>
212 <url>Url</url>
213 <timestamp>Fri Sep 1 13:26:41 CDT 2017</timestamp>
214 </index>";
215 let response = Vidx::from_string(good_string).unwrap();
216 assert_eq!(response.vendor, String::from("Vendor"));
217 assert_eq!(response.url, "Url");
218 assert_eq!(
219 response.timestamp,
220 Some(String::from("Fri Sep 1 13:26:41 CDT"))
221 );
222 }
223}