Skip to content

Commit 8c20d17

Browse files
authored
Merge pull request #252 from rust-embedded/validate
validate_all
2 parents f72c321 + dee49b0 commit 8c20d17

File tree

7 files changed

+114
-8
lines changed

7 files changed

+114
-8
lines changed

svd-rs/CHANGELOG.md

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

88
## Unreleased
99

10+
- fix `validate` on `Disabled` level, remove `mut`
11+
- add `validate_all` for `Device` and childrens for recursive tree check
12+
1013
## [v0.14.5] - 2023-11-22
1114

1215
- `default_value` for `EnumeratedValues`

svd-rs/src/cluster.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::{
77
BuildError, Description, DimElement, EmptyToNone, MaybeArray, Name, Register, RegisterCluster,
88
RegisterProperties, SvdError, ValidateLevel,
99
};
10+
use std::ops::Deref;
1011

1112
/// Cluster describes a sequence of neighboring registers within a peripheral.
1213
pub type Cluster = MaybeArray<ClusterInfo>;
@@ -253,6 +254,17 @@ impl ClusterInfo {
253254
}
254255
Ok(())
255256
}
257+
/// Validate the [`ClusterInfo`] recursively
258+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
259+
self.default_register_properties.validate(lvl)?;
260+
for r in self.registers() {
261+
r.validate_all(lvl)?;
262+
}
263+
for c in self.clusters() {
264+
c.validate_all(lvl)?;
265+
}
266+
self.validate(lvl)
267+
}
256268

257269
/// Returns iterator over all descendant registers
258270
#[deprecated(since = "0.12.1", note = "Please use `all_registers` instead")]
@@ -329,6 +341,16 @@ impl ClusterInfo {
329341
}
330342
}
331343

344+
impl Cluster {
345+
/// Validate the [`Cluster`] recursively
346+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
347+
if let Self::Array(_, dim) = self {
348+
dim.validate(lvl)?;
349+
}
350+
self.deref().validate_all(lvl)
351+
}
352+
}
353+
332354
impl Name for ClusterInfo {
333355
fn name(&self) -> &str {
334356
&self.name

svd-rs/src/device.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ impl Device {
372372
}
373373
self.validate(lvl)
374374
}
375+
375376
/// Validate the [`Device`]
376377
pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
377378
if !lvl.is_disabled() {
@@ -382,6 +383,17 @@ impl Device {
382383
}
383384
Ok(())
384385
}
386+
/// Validate the [`Device`] recursively
387+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
388+
if let Some(cpu) = self.cpu.as_ref() {
389+
cpu.validate(lvl)?;
390+
}
391+
self.default_register_properties.validate(lvl)?;
392+
for p in &self.peripherals {
393+
p.validate_all(lvl)?;
394+
}
395+
self.validate(lvl)
396+
}
385397

386398
/// Get peripheral by name
387399
pub fn get_peripheral(&self, name: &str) -> Option<&Peripheral> {

svd-rs/src/enumeratedvalues.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,7 @@ impl EnumeratedValuesBuilder {
100100
impl EnumeratedValues {
101101
/// Return default value if present
102102
pub fn default_value(&self) -> Option<&EnumeratedValue> {
103-
for v in &self.values {
104-
if v.is_default() {
105-
return Some(v);
106-
}
107-
}
108-
None
103+
self.values.iter().find(|&v| v.is_default())
109104
}
110105

111106
/// Make a builder for [`EnumeratedValues`]
@@ -135,7 +130,7 @@ impl EnumeratedValues {
135130
}
136131
self.validate(lvl)
137132
}
138-
/// Validate the [`EnumeratedValues`].
133+
/// Validate the [`EnumeratedValues`]
139134
pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
140135
if !lvl.is_disabled() {
141136
if lvl.is_strict() {
@@ -157,6 +152,13 @@ impl EnumeratedValues {
157152
Ok(())
158153
}
159154
}
155+
/// Validate the [`EnumeratedValues`] recursively.
156+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
157+
for ev in &self.values {
158+
ev.validate(lvl)?;
159+
}
160+
self.validate(lvl)
161+
}
160162
pub(crate) fn check_range(&self, range: core::ops::Range<u64>) -> Result<(), SvdError> {
161163
for v in self.values.iter() {
162164
v.check_range(&range)?;

svd-rs/src/field.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::{
44
MaybeArray, ModifiedWriteValues, Name, ReadAction, SvdError, Usage, ValidateLevel,
55
WriteConstraint,
66
};
7+
use std::ops::Deref;
78

89
/// Describes a field or fields of a [register](crate::RegisterInfo).
910
pub type Field = MaybeArray<FieldInfo>;
@@ -334,6 +335,13 @@ impl FieldInfo {
334335

335336
Ok(())
336337
}
338+
/// Validate the [`FieldInfo`] recursively
339+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
340+
for evs in &self.enumerated_values {
341+
evs.validate_all(lvl)?;
342+
}
343+
self.validate(lvl)
344+
}
337345

338346
/// Get bit offset
339347
pub fn bit_offset(&self) -> u32 {
@@ -377,6 +385,16 @@ impl FieldInfo {
377385
}
378386
}
379387

388+
impl Field {
389+
/// Validate the [`Field`] recursively
390+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
391+
if let Self::Array(_, dim) = self {
392+
dim.validate(lvl)?;
393+
}
394+
self.deref().validate_all(lvl)
395+
}
396+
}
397+
380398
impl Name for FieldInfo {
381399
fn name(&self) -> &str {
382400
&self.name

svd-rs/src/peripheral.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::{
77
AddressBlock, BuildError, Cluster, Description, DimElement, EmptyToNone, Interrupt, MaybeArray,
88
Name, Register, RegisterCluster, RegisterProperties, SvdError, ValidateLevel,
99
};
10+
use std::ops::Deref;
1011

1112
/// A single peripheral or array of peripherals
1213
pub type Peripheral = MaybeArray<PeripheralInfo>;
@@ -369,7 +370,7 @@ impl PeripheralInfo {
369370
self.validate(lvl)
370371
}
371372

372-
/// Validate the [`Peripheral`]
373+
/// Validate the [`PeripheralInfo`]
373374
pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
374375
if !lvl.is_disabled() {
375376
// TODO
@@ -388,6 +389,25 @@ impl PeripheralInfo {
388389
}
389390
Ok(())
390391
}
392+
/// Validate the [`PeripheralInfo`] recursively
393+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
394+
if let Some(abs) = self.address_block.as_ref() {
395+
for ab in abs {
396+
ab.validate(lvl)?;
397+
}
398+
}
399+
for i in &self.interrupt {
400+
i.validate(lvl)?;
401+
}
402+
self.default_register_properties.validate(lvl)?;
403+
for r in self.registers() {
404+
r.validate_all(lvl)?;
405+
}
406+
for c in self.clusters() {
407+
c.validate_all(lvl)?;
408+
}
409+
self.validate(lvl)
410+
}
391411

392412
/// Returns iterator over child registers
393413
pub fn registers(&self) -> RegisterIter {
@@ -492,6 +512,16 @@ impl PeripheralInfo {
492512
}
493513
}
494514

515+
impl Peripheral {
516+
/// Validate the [`Peripheral`] recursively
517+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
518+
if let Self::Array(_, dim) = self {
519+
dim.validate(lvl)?;
520+
}
521+
self.deref().validate_all(lvl)
522+
}
523+
}
524+
495525
impl Name for PeripheralInfo {
496526
fn name(&self) -> &str {
497527
&self.name

svd-rs/src/register.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::{
44
ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel,
55
WriteConstraint,
66
};
7+
use std::ops::Deref;
78

89
/// A single register or array of registers. A register is a named, programmable resource that belongs to a [peripheral](crate::Peripheral).
910
pub type Register = MaybeArray<RegisterInfo>;
@@ -358,6 +359,14 @@ impl RegisterInfo {
358359
}
359360
Ok(())
360361
}
362+
/// Validate the [`RegisterInfo`] recursively
363+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
364+
self.properties.validate(lvl)?;
365+
for f in self.fields() {
366+
f.validate_all(lvl)?;
367+
}
368+
self.validate(lvl)
369+
}
361370

362371
/// Returns iterator over child fields
363372
pub fn fields(&self) -> std::slice::Iter<Field> {
@@ -386,6 +395,16 @@ impl RegisterInfo {
386395
}
387396
}
388397

398+
impl Register {
399+
/// Validate the [`Register`] recursively
400+
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
401+
if let Self::Array(_, dim) = self {
402+
dim.validate(lvl)?;
403+
}
404+
self.deref().validate_all(lvl)
405+
}
406+
}
407+
389408
impl Name for RegisterInfo {
390409
fn name(&self) -> &str {
391410
&self.name

0 commit comments

Comments
 (0)