Skip to content

Commit a08622a

Browse files
bors[bot]burrbull
andauthored
Merge #174
174: builder for Interrupt r=Emilgardis a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 820c826 + 4246213 commit a08622a

File tree

4 files changed

+106
-13
lines changed

4 files changed

+106
-13
lines changed

svd-parser/src/interrupt.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@ impl Parse for Interrupt {
66
type Error = SVDErrorAt;
77
type Config = Config;
88

9-
fn parse(tree: &Node, _config: &Self::Config) -> Result<Self, Self::Error> {
9+
fn parse(tree: &Node, config: &Self::Config) -> Result<Self, Self::Error> {
1010
if !tree.has_tag_name("interrupt") {
1111
return Err(SVDError::NotExpectedTag("interrupt".to_string()).at(tree.id()));
1212
}
1313
let name = tree.get_child_text("name")?;
1414

15-
Ok(Interrupt {
16-
name,
17-
description: tree.get_child_text_opt("description")?,
18-
value: tree.get_child_u32("value")?,
19-
})
15+
Interrupt::builder()
16+
.name(name)
17+
.description(tree.get_child_text_opt("description")?)
18+
.value(tree.get_child_u32("value")?)
19+
.build(config.validate_level)
20+
.map_err(|e| SVDError::from(e).at(tree.id()))
2021
}
2122
}

svd-rs/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
- Don't clone when serialize
1111
- Add optional entries to `Cpu`
12-
- `AddressBlock` now uses builder
12+
- `AddressBlock` & `Interrupt` now use builders
1313
- Add `dim_name` and `dim_array_index` to `DimElement`
1414
- Add `alternate_peripheral`, `prepend_to_name`, `append_to_name`,
1515
`header_struct_name` to `PeripheralInfo`, `alternate_cluster` to `ClusterInfo`

svd-rs/src/interrupt.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
use super::{BuildError, SvdError, ValidateLevel};
2+
13
/// Describes an interrupt in the device
24
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
35
#[derive(Clone, Debug, PartialEq)]
6+
#[non_exhaustive]
47
pub struct Interrupt {
58
/// The string represents the interrupt name
69
pub name: String,
@@ -15,3 +18,91 @@ pub struct Interrupt {
1518
/// Represents the enumeration index value associated to the interrupt
1619
pub value: u32,
1720
}
21+
22+
/// Builder for [`Interrupt`]
23+
#[derive(Clone, Debug, Default, PartialEq)]
24+
pub struct InterruptBuilder {
25+
name: Option<String>,
26+
description: Option<String>,
27+
value: Option<u32>,
28+
}
29+
30+
impl From<Interrupt> for InterruptBuilder {
31+
fn from(d: Interrupt) -> Self {
32+
Self {
33+
name: Some(d.name),
34+
description: d.description,
35+
value: Some(d.value),
36+
}
37+
}
38+
}
39+
40+
impl InterruptBuilder {
41+
/// Set the name of the interrupt
42+
pub fn name(mut self, value: String) -> Self {
43+
self.name = Some(value);
44+
self
45+
}
46+
/// Set the description of the interrupt
47+
pub fn description(mut self, value: Option<String>) -> Self {
48+
self.description = value;
49+
self
50+
}
51+
/// Set the value of the interrupt
52+
pub fn value(mut self, value: u32) -> Self {
53+
self.value = Some(value);
54+
self
55+
}
56+
/// Validate and build a [`Interrupt`].
57+
pub fn build(self, lvl: ValidateLevel) -> Result<Interrupt, SvdError> {
58+
let mut de = Interrupt {
59+
name: self
60+
.name
61+
.ok_or_else(|| BuildError::Uninitialized("name".to_string()))?,
62+
description: self.description,
63+
value: self
64+
.value
65+
.ok_or_else(|| BuildError::Uninitialized("value".to_string()))?,
66+
};
67+
if !lvl.is_disabled() {
68+
de.validate(lvl)?;
69+
}
70+
Ok(de)
71+
}
72+
}
73+
74+
impl Interrupt {
75+
/// Make a builder for [`Interrupt`]
76+
pub fn builder() -> InterruptBuilder {
77+
InterruptBuilder::default()
78+
}
79+
/// Modify an existing [`Interrupt`] based on a [builder](InterruptBuilder).
80+
pub fn modify_from(
81+
&mut self,
82+
builder: InterruptBuilder,
83+
lvl: ValidateLevel,
84+
) -> Result<(), SvdError> {
85+
if let Some(name) = builder.name {
86+
self.name = name;
87+
}
88+
if builder.description.is_some() {
89+
self.description = builder.description;
90+
}
91+
if let Some(value) = builder.value {
92+
self.value = value;
93+
}
94+
if !lvl.is_disabled() {
95+
self.validate(lvl)
96+
} else {
97+
Ok(())
98+
}
99+
}
100+
/// Validate the [`Interrupt`].
101+
///
102+
/// # Notes
103+
///
104+
/// This doesn't do anything.
105+
pub fn validate(&mut self, _lvl: ValidateLevel) -> Result<(), SvdError> {
106+
Ok(())
107+
}
108+
}

tests/src/interrupt.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use super::run_test;
2-
use crate::svd::Interrupt;
2+
use crate::svd::{Interrupt, ValidateLevel};
33

44
#[test]
55
fn decode_encode() {
66
let tests = vec![(
7-
Interrupt {
8-
name: String::from("test"),
9-
description: Some(String::from("description")),
10-
value: 14,
11-
},
7+
Interrupt::builder()
8+
.name("test".to_string())
9+
.description(Some("description".to_string()))
10+
.value(14)
11+
.build(ValidateLevel::Strict)
12+
.unwrap(),
1213
"
1314
<interrupt>
1415
<name>test</name>

0 commit comments

Comments
 (0)