1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#![allow(clippy::manual_strip)]
use roxmltree::Node;
use super::{Config, ElementExt, Parse, SVDError, SVDErrorAt};
impl Parse for u32 {
type Object = u32;
type Error = SVDErrorAt;
type Config = ();
fn parse(tree: &Node, _config: &Self::Config) -> Result<u32, Self::Error> {
let text = tree.get_text()?;
(if text.starts_with("0x") || text.starts_with("0X") {
u32::from_str_radix(&text["0x".len()..], 16)
} else if text.starts_with('#') {
u32::from_str_radix(
&str::replace(&text.to_lowercase()["#".len()..], "x", "0"),
2,
)
} else if text.starts_with("0b") {
u32::from_str_radix(&str::replace(&text["0b".len()..], "x", "0"), 2)
} else {
text.parse::<u32>()
})
.map_err(|e| SVDError::from(e).at(tree.id()))
}
}
impl Parse for u64 {
type Object = u64;
type Error = SVDErrorAt;
type Config = ();
fn parse(tree: &Node, _config: &Self::Config) -> Result<u64, Self::Error> {
let text = tree.get_text()?;
(if text.starts_with("0x") || text.starts_with("0X") {
u64::from_str_radix(&text["0x".len()..], 16)
} else if text.starts_with('#') {
u64::from_str_radix(
&str::replace(&text.to_lowercase()["#".len()..], "x", "0"),
2,
)
} else if text.starts_with("0b") {
u64::from_str_radix(&str::replace(&text["0b".len()..], "x", "0"), 2)
} else {
text.parse::<u64>()
})
.map_err(|e| SVDError::from(e).at(tree.id()))
}
}
pub struct BoolParse;
impl Parse for BoolParse {
type Object = bool;
type Error = SVDErrorAt;
type Config = ();
fn parse(tree: &Node, _config: &Self::Config) -> Result<bool, Self::Error> {
let text = tree.get_text()?;
match text {
"0" => Ok(false),
"1" => Ok(true),
_ => match text.parse() {
Ok(b) => Ok(b),
Err(e) => Err(SVDError::InvalidBooleanValue(text.into(), e).at(tree.id())),
},
}
}
}
pub struct DimIndex;
impl Parse for DimIndex {
type Object = Vec<String>;
type Error = SVDErrorAt;
type Config = Config;
fn parse(tree: &Node, _config: &Self::Config) -> Result<Vec<String>, Self::Error> {
let text = tree.get_text()?;
if text.contains('-') {
let mut parts = text.splitn(2, '-');
let start = parts
.next()
.ok_or_else(|| SVDError::DimIndexParse.at(tree.id()))?
.parse::<u32>()
.map_err(|e| SVDError::from(e).at(tree.id()))?;
let end = parts
.next()
.ok_or_else(|| SVDError::DimIndexParse.at(tree.id()))?
.parse::<u32>()
.map_err(|e| SVDError::from(e).at(tree.id()))?;
Ok((start..=end).map(|i| i.to_string()).collect())
} else {
Ok(text.split(',').map(|s| s.to_string()).collect())
}
}
}