1use roxmltree::Node;
5
6use super::types::BoolParse;
7use super::{Parse, SVDError, SVDErrorAt};
8
9pub trait ElementExt {
11 fn get_child<K>(&self, k: K) -> Option<Node>
12 where
13 K: AsRef<str>;
14 fn get_child_text_opt<K>(&self, k: K) -> Result<Option<String>, SVDErrorAt>
15 where
16 K: AsRef<str>;
17 fn get_child_text<K>(&self, k: K) -> Result<String, SVDErrorAt>
18 where
19 K: AsRef<str>;
20
21 fn get_text(&self) -> Result<&str, SVDErrorAt>;
22
23 fn get_child_elem(&self, n: &str) -> Result<Node, SVDErrorAt>;
24 fn get_child_u32(&self, n: &str) -> Result<u32, SVDErrorAt>;
25 fn get_child_u64(&self, n: &str) -> Result<u64, SVDErrorAt>;
26 fn get_child_bool(&self, n: &str) -> Result<bool, SVDErrorAt>;
27
28 fn debug(&self);
29}
30
31impl ElementExt for Node<'_, '_> {
33 fn get_child<K>(&self, k: K) -> Option<Node>
34 where
35 K: AsRef<str>,
36 {
37 self.children().find(|&c| c.has_tag_name(k.as_ref()))
38 }
39 fn get_child_text_opt<K>(&self, k: K) -> Result<Option<String>, SVDErrorAt>
40 where
41 K: AsRef<str>,
42 {
43 if let Some(child) = self.get_child(k) {
44 match child.get_text() {
45 Err(e) => {
46 match e {
48 SVDErrorAt {
49 error: SVDError::EmptyTag(_),
50 ..
51 } => Ok(None),
52 _ => Err(e),
53 }
54 }
55 Ok(s) => Ok(Some(s.to_string())),
56 }
57 } else {
58 Ok(None)
59 }
60 }
61 fn get_child_text<K>(&self, k: K) -> Result<String, SVDErrorAt>
62 where
63 K: AsRef<str>,
64 {
65 let k = k.as_ref();
66 self.get_child_text_opt(k)?
67 .ok_or_else(|| SVDError::MissingTag(k.to_string()).at(self.id()))
68 }
69
70 fn get_text(&self) -> Result<&str, SVDErrorAt> {
72 match self.text() {
73 Some(s) => Ok(s.trim()),
75 None => Err(SVDError::EmptyTag(self.tag_name().name().to_string()).at(self.id())),
79 }
80 }
81
82 fn get_child_elem(&self, n: &str) -> Result<Node, SVDErrorAt> {
84 self.get_child(n)
85 .ok_or_else(|| SVDError::MissingTag(n.to_string()).at(self.id()))
86 }
87
88 fn get_child_u32(&self, n: &str) -> Result<u32, SVDErrorAt> {
90 let s = self.get_child_elem(n)?;
91 u32::parse(&s, &())
92 }
93
94 fn get_child_u64(&self, n: &str) -> Result<u64, SVDErrorAt> {
96 let s = self.get_child_elem(n)?;
97 u64::parse(&s, &())
98 }
99
100 fn get_child_bool(&self, n: &str) -> Result<bool, SVDErrorAt> {
102 let s = self.get_child_elem(n)?;
103 BoolParse::parse(&s, &())
104 }
105
106 fn debug(&self) {
107 let name = self.tag_name().name();
108 println!("<{}>", name);
109 for c in self.children() {
110 println!("{}: {:?}", c.tag_name().name(), c.text())
111 }
112 println!("</{}>", name);
113 }
114}