Skip to content

Commit 599f4a2

Browse files
bors[bot]burrbull
andauthored
Merge #144
144: RegIter r=therealprof a=burrbull r? @therealprof Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 0896532 + 13c0e65 commit 599f4a2

File tree

6 files changed

+136
-6
lines changed

6 files changed

+136
-6
lines changed

CHANGELOG.md

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

88
## [Unreleased]
99

10+
- Added `reg_iter`, `reg_iter_mut` methods on `Peripheral` and `Cluster`
11+
- Added `DerefMut` for `Cluster`, `Register` and `Field`
1012
- Added `display_name` to `RegisterInfo`
1113
- Added implementations of `From<Type>` for `TypeBuilder`'s
1214

src/svd/cluster.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::ops::Deref;
1+
use core::ops::{Deref, DerefMut};
22
use xmltree::Element;
33

44
use crate::types::Parse;
@@ -26,6 +26,15 @@ impl Deref for Cluster {
2626
}
2727
}
2828

29+
impl DerefMut for Cluster {
30+
fn deref_mut(&mut self) -> &mut ClusterInfo {
31+
match self {
32+
Cluster::Single(info) => info,
33+
Cluster::Array(info, _) => info,
34+
}
35+
}
36+
}
37+
2938
impl Parse for Cluster {
3039
type Object = Self;
3140
type Error = anyhow::Error;

src/svd/clusterinfo.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ use crate::encode::{Encode, EncodeChildren};
77
use crate::new_element;
88

99
use crate::error::*;
10-
use crate::svd::{registercluster::RegisterCluster, registerproperties::RegisterProperties};
10+
use crate::svd::{
11+
register::{RegIter, RegIterMut},
12+
registercluster::RegisterCluster,
13+
registerproperties::RegisterProperties,
14+
};
1115

1216
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
1317
#[derive(Clone, Debug, PartialEq)]
@@ -161,6 +165,24 @@ impl ClusterInfo {
161165
})
162166
.build()
163167
}
168+
169+
/// returns iterator over all registers cluster contains
170+
pub fn reg_iter(&self) -> RegIter {
171+
let mut rem: Vec<&RegisterCluster> = Vec::with_capacity(self.children.len());
172+
for r in self.children.iter().rev() {
173+
rem.push(r);
174+
}
175+
RegIter { rem }
176+
}
177+
178+
/// returns mutable iterator over all registers cluster contains
179+
pub fn reg_iter_mut(&mut self) -> RegIterMut {
180+
let mut rem: Vec<&mut RegisterCluster> = Vec::with_capacity(self.children.len());
181+
for r in self.children.iter_mut().rev() {
182+
rem.push(r);
183+
}
184+
RegIterMut { rem }
185+
}
164186
}
165187

166188
impl Encode for ClusterInfo {

src/svd/field.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::ops::Deref;
1+
use core::ops::{Deref, DerefMut};
22

33
use xmltree::Element;
44

@@ -28,6 +28,15 @@ impl Deref for Field {
2828
}
2929
}
3030

31+
impl DerefMut for Field {
32+
fn deref_mut(&mut self) -> &mut FieldInfo {
33+
match self {
34+
Field::Single(info) => info,
35+
Field::Array(info, _) => info,
36+
}
37+
}
38+
}
39+
3140
impl Parse for Field {
3241
type Object = Self;
3342
type Error = anyhow::Error;

src/svd/peripheral.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use crate::types::Parse;
1212

1313
use crate::error::*;
1414
use crate::svd::{
15-
addressblock::AddressBlock, interrupt::Interrupt, registercluster::RegisterCluster,
15+
addressblock::AddressBlock,
16+
interrupt::Interrupt,
17+
register::{RegIter, RegIterMut},
18+
registercluster::RegisterCluster,
1619
registerproperties::RegisterProperties,
1720
};
1821

@@ -185,6 +188,32 @@ impl Peripheral {
185188
}
186189
Ok(self)
187190
}
191+
192+
/// returns iterator over all registers peripheral contains
193+
pub fn reg_iter(&self) -> RegIter {
194+
if let Some(regs) = &self.registers {
195+
let mut rem: Vec<&RegisterCluster> = Vec::with_capacity(regs.len());
196+
for r in regs.iter().rev() {
197+
rem.push(r);
198+
}
199+
RegIter { rem }
200+
} else {
201+
RegIter { rem: Vec::new() }
202+
}
203+
}
204+
205+
/// returns mutable iterator over all registers peripheral contains
206+
pub fn reg_iter_mut(&mut self) -> RegIterMut {
207+
if let Some(regs) = &mut self.registers {
208+
let mut rem: Vec<&mut RegisterCluster> = Vec::with_capacity(regs.len());
209+
for r in regs.iter_mut().rev() {
210+
rem.push(r);
211+
}
212+
RegIterMut { rem }
213+
} else {
214+
RegIterMut { rem: Vec::new() }
215+
}
216+
}
188217
}
189218

190219
impl Parse for Peripheral {

src/svd/register.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::ops::Deref;
1+
use core::ops::{Deref, DerefMut};
22

33
use xmltree::Element;
44

@@ -8,7 +8,9 @@ use crate::elementext::ElementExt;
88

99
use crate::encode::Encode;
1010
use crate::error::*;
11-
use crate::svd::{dimelement::DimElement, registerinfo::RegisterInfo};
11+
use crate::svd::{
12+
dimelement::DimElement, registercluster::RegisterCluster, registerinfo::RegisterInfo,
13+
};
1214
use anyhow::Result;
1315

1416
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
@@ -29,6 +31,15 @@ impl Deref for Register {
2931
}
3032
}
3133

34+
impl DerefMut for Register {
35+
fn deref_mut(&mut self) -> &mut RegisterInfo {
36+
match self {
37+
Register::Single(info) => info,
38+
Register::Array(info, _) => info,
39+
}
40+
}
41+
}
42+
3243
impl Parse for Register {
3344
type Object = Self;
3445
type Error = anyhow::Error;
@@ -103,3 +114,51 @@ mod tests {
103114
run_test::<Register>(&tests[..]);
104115
}
105116
}
117+
118+
/// Register iterator
119+
pub struct RegIter<'a> {
120+
pub(crate) rem: Vec<&'a RegisterCluster>,
121+
}
122+
123+
impl<'a> std::iter::Iterator for RegIter<'a> {
124+
type Item = &'a Register;
125+
fn next(&mut self) -> Option<Self::Item> {
126+
while let Some(b) = self.rem.pop() {
127+
match b {
128+
RegisterCluster::Register(reg) => {
129+
return Some(reg);
130+
}
131+
RegisterCluster::Cluster(cluster) => {
132+
for c in cluster.children.iter().rev() {
133+
self.rem.push(c);
134+
}
135+
}
136+
}
137+
}
138+
None
139+
}
140+
}
141+
142+
/// Mutable register iterator
143+
pub struct RegIterMut<'a> {
144+
pub(crate) rem: Vec<&'a mut RegisterCluster>,
145+
}
146+
147+
impl<'a> std::iter::Iterator for RegIterMut<'a> {
148+
type Item = &'a mut Register;
149+
fn next(&mut self) -> Option<Self::Item> {
150+
while let Some(b) = self.rem.pop() {
151+
match b {
152+
RegisterCluster::Register(reg) => {
153+
return Some(reg);
154+
}
155+
RegisterCluster::Cluster(cluster) => {
156+
for c in cluster.children.iter_mut().rev() {
157+
self.rem.push(c);
158+
}
159+
}
160+
}
161+
}
162+
None
163+
}
164+
}

0 commit comments

Comments
 (0)