-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathsvd_reader.rs
106 lines (94 loc) · 2.75 KB
/
svd_reader.rs
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
use quick_xml::de;
use serde::Deserialize;
use std::io::{BufReader, Read};
#[derive(Deserialize, Debug)]
struct Svd {
peripherals: PeripheralList,
}
#[derive(Deserialize, Debug)]
struct PeripheralList {
peripheral: Vec<PeripheralXml>,
}
#[derive(Deserialize, Debug)]
struct PeripheralXml {
name: String,
// some peripherals have no interrupts
interrupt: Option<Vec<Interrupt>>,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
pub struct Interrupt {
pub name: String,
pub description: Option<String>,
pub value: u32,
}
#[derive(Debug, PartialEq, Eq)]
pub struct Peripheral {
pub name: String,
pub interrupt: Vec<Interrupt>,
}
/// get all peripherals that contain at least one interrupt
pub fn peripherals_with_interrupts<R: Read>(svd: R) -> impl Iterator<Item = Peripheral> {
let reader = BufReader::new(svd);
let svd: Svd = de::from_reader(reader).expect("svd not formatted correctly");
let peripheral_list = svd.peripherals.peripheral;
peripheral_list.into_iter().filter_map(|p| {
if let Some(interrupt) = p.interrupt {
Some(Peripheral {
name: p.name,
interrupt,
})
} else {
None
}
})
}
#[cfg(test)]
mod tests {
use super::*;
static SVD: &str = r"<device>
<name>Test Device</name>
<peripherals>
<peripheral>
<name>PeriphA</name>
<interrupt>
<name>INT_A1</name>
<description>Interrupt A1</description>
<value>1</value>
</interrupt>
</peripheral>
<peripheral>
<name>PeriphB</name>
<interrupt>
<name>INT_B3</name>
<description>Interrupt B3</description>
<value>3</value>
</interrupt>
</peripheral>
</peripherals>
</device>
";
#[test]
fn peripherals_interrupts_are_parsed_correctly() {
let svd = SVD.as_bytes();
let actual_peripherals: Vec<Peripheral> = peripherals_with_interrupts(svd).collect();
let expected_peripherals = vec![
Peripheral {
name: "PeriphA".to_string(),
interrupt: vec![Interrupt {
name: "INT_A1".to_string(),
description: Some("Interrupt A1".to_string()),
value: 1,
}],
},
Peripheral {
name: "PeriphB".to_string(),
interrupt: vec![Interrupt {
name: "INT_B3".to_string(),
description: Some("Interrupt B3".to_string()),
value: 3,
}],
},
];
assert_eq!(actual_peripherals, expected_peripherals);
}
}