Skip to content

Commit 376727e

Browse files
bors[bot]burrbull
andauthored
Merge #170
170: builder for AddressBlock r=Emilgardis a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 3ac31f0 + b858a79 commit 376727e

File tree

4 files changed

+122
-14
lines changed

4 files changed

+122
-14
lines changed

svd-parser/src/addressblock.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ impl Parse for AddressBlock {
77
type Config = Config;
88

99
fn parse(tree: &Node, config: &Self::Config) -> Result<Self, Self::Error> {
10-
Ok(Self {
11-
offset: tree.get_child_u32("offset")?,
12-
size: tree.get_child_u32("size")?,
13-
usage: AddressBlockUsage::parse(&tree.get_child_elem("usage")?, config)?,
14-
protection: optional::<Protection>("protection", tree, config)?,
15-
})
10+
Self::builder()
11+
.offset(tree.get_child_u32("offset")?)
12+
.size(tree.get_child_u32("size")?)
13+
.usage(AddressBlockUsage::parse(
14+
&tree.get_child_elem("usage")?,
15+
config,
16+
)?)
17+
.protection(optional::<Protection>("protection", tree, config)?)
18+
.build(config.validate_level)
19+
.map_err(|e| SVDError::from(e).at(tree.id()))
1620
}
1721
}
1822

svd-rs/CHANGELOG.md

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

88
## Unreleased
99

10+
- `AddressBlock` now uses builder
1011
- Add `dim_name` and `dim_array_index` to `DimElement`
1112
- Add `alternate_peripheral`, `prepend_to_name`, `append_to_name`,
1213
`header_struct_name` to `PeripheralInfo`, `alternate_cluster` to `ClusterInfo`

svd-rs/src/addressblock.rs

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use super::Protection;
1+
use super::{BuildError, Protection, SvdError, ValidateLevel};
22

33
/// An uniquely mapped address block to a peripheral
44
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
55
#[derive(Clone, Debug, PartialEq)]
6+
#[non_exhaustive]
67
pub struct AddressBlock {
78
/// Specifies the start address of an address block relative to the peripheral [`baseAddress`](crate::Peripheral::base_address).
89
pub offset: u32,
@@ -60,3 +61,104 @@ impl AddressBlockUsage {
6061
}
6162
}
6263
}
64+
65+
/// Builder for [`AddressBlock`]
66+
#[derive(Clone, Debug, Default, PartialEq)]
67+
pub struct AddressBlockBuilder {
68+
offset: Option<u32>,
69+
size: Option<u32>,
70+
usage: Option<AddressBlockUsage>,
71+
protection: Option<Protection>,
72+
}
73+
74+
impl From<AddressBlock> for AddressBlockBuilder {
75+
fn from(d: AddressBlock) -> Self {
76+
Self {
77+
offset: Some(d.offset),
78+
size: Some(d.size),
79+
usage: Some(d.usage),
80+
protection: d.protection,
81+
}
82+
}
83+
}
84+
85+
impl AddressBlockBuilder {
86+
/// Set the offset of the block
87+
pub fn offset(mut self, value: u32) -> Self {
88+
self.offset = Some(value);
89+
self
90+
}
91+
/// Set the size of the block
92+
pub fn size(mut self, value: u32) -> Self {
93+
self.size = Some(value);
94+
self
95+
}
96+
/// Set the usage of the block
97+
pub fn usage(mut self, value: AddressBlockUsage) -> Self {
98+
self.usage = Some(value);
99+
self
100+
}
101+
/// Set the protection of the block
102+
pub fn protection(mut self, value: Option<Protection>) -> Self {
103+
self.protection = value;
104+
self
105+
}
106+
/// Validate and build a [`AddressBlock`].
107+
pub fn build(self, lvl: ValidateLevel) -> Result<AddressBlock, SvdError> {
108+
let mut de = AddressBlock {
109+
offset: self
110+
.offset
111+
.ok_or_else(|| BuildError::Uninitialized("offset".to_string()))?,
112+
size: self
113+
.size
114+
.ok_or_else(|| BuildError::Uninitialized("size".to_string()))?,
115+
usage: self
116+
.usage
117+
.ok_or_else(|| BuildError::Uninitialized("usage".to_string()))?,
118+
protection: self.protection,
119+
};
120+
if !lvl.is_disabled() {
121+
de.validate(lvl)?;
122+
}
123+
Ok(de)
124+
}
125+
}
126+
127+
impl AddressBlock {
128+
/// Make a builder for [`AddressBlock`]
129+
pub fn builder() -> AddressBlockBuilder {
130+
AddressBlockBuilder::default()
131+
}
132+
/// Modify an existing [`AddressBlock`] based on a [builder](AddressBlockBuilder).
133+
pub fn modify_from(
134+
&mut self,
135+
builder: AddressBlockBuilder,
136+
lvl: ValidateLevel,
137+
) -> Result<(), SvdError> {
138+
if let Some(offset) = builder.offset {
139+
self.offset = offset;
140+
}
141+
if let Some(size) = builder.size {
142+
self.size = size;
143+
}
144+
if let Some(usage) = builder.usage {
145+
self.usage = usage;
146+
}
147+
if builder.protection.is_some() {
148+
self.protection = builder.protection;
149+
}
150+
if !lvl.is_disabled() {
151+
self.validate(lvl)
152+
} else {
153+
Ok(())
154+
}
155+
}
156+
/// Validate the [`AddressBlock`].
157+
///
158+
/// # Notes
159+
///
160+
/// This doesn't do anything.
161+
pub fn validate(&mut self, _lvl: ValidateLevel) -> Result<(), SvdError> {
162+
Ok(())
163+
}
164+
}

tests/src/addressblock.rs

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

44
#[test]
55
fn decode_encode() {
66
let tests = vec![(
7-
AddressBlock {
8-
offset: 0,
9-
size: 0x00000800,
10-
usage: AddressBlockUsage::Registers,
11-
protection: None,
12-
},
7+
AddressBlock::builder()
8+
.offset(0)
9+
.size(0x00000800)
10+
.usage(AddressBlockUsage::Registers)
11+
.protection(None)
12+
.build(ValidateLevel::Strict)
13+
.unwrap(),
1314
"<addressBlock>
1415
<offset>0x0</offset>
1516
<size>0x800</size>

0 commit comments

Comments
 (0)