Skip to content

Commit

Permalink
Merge pull request #252 from rust-embedded/validate
Browse files Browse the repository at this point in the history
validate_all
  • Loading branch information
burrbull authored Nov 29, 2023
2 parents f72c321 + dee49b0 commit 8c20d17
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 8 deletions.
3 changes: 3 additions & 0 deletions svd-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

- fix `validate` on `Disabled` level, remove `mut`
- add `validate_all` for `Device` and childrens for recursive tree check

## [v0.14.5] - 2023-11-22

- `default_value` for `EnumeratedValues`
Expand Down
22 changes: 22 additions & 0 deletions svd-rs/src/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::{
BuildError, Description, DimElement, EmptyToNone, MaybeArray, Name, Register, RegisterCluster,
RegisterProperties, SvdError, ValidateLevel,
};
use std::ops::Deref;

/// Cluster describes a sequence of neighboring registers within a peripheral.
pub type Cluster = MaybeArray<ClusterInfo>;
Expand Down Expand Up @@ -253,6 +254,17 @@ impl ClusterInfo {
}
Ok(())
}
/// Validate the [`ClusterInfo`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
self.default_register_properties.validate(lvl)?;
for r in self.registers() {
r.validate_all(lvl)?;
}
for c in self.clusters() {
c.validate_all(lvl)?;
}
self.validate(lvl)
}

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

impl Cluster {
/// Validate the [`Cluster`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if let Self::Array(_, dim) = self {
dim.validate(lvl)?;
}
self.deref().validate_all(lvl)
}
}

impl Name for ClusterInfo {
fn name(&self) -> &str {
&self.name
Expand Down
12 changes: 12 additions & 0 deletions svd-rs/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ impl Device {
}
self.validate(lvl)
}

/// Validate the [`Device`]
pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if !lvl.is_disabled() {
Expand All @@ -382,6 +383,17 @@ impl Device {
}
Ok(())
}
/// Validate the [`Device`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if let Some(cpu) = self.cpu.as_ref() {
cpu.validate(lvl)?;
}
self.default_register_properties.validate(lvl)?;
for p in &self.peripherals {
p.validate_all(lvl)?;
}
self.validate(lvl)
}

/// Get peripheral by name
pub fn get_peripheral(&self, name: &str) -> Option<&Peripheral> {
Expand Down
16 changes: 9 additions & 7 deletions svd-rs/src/enumeratedvalues.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,7 @@ impl EnumeratedValuesBuilder {
impl EnumeratedValues {
/// Return default value if present
pub fn default_value(&self) -> Option<&EnumeratedValue> {
for v in &self.values {
if v.is_default() {
return Some(v);
}
}
None
self.values.iter().find(|&v| v.is_default())
}

/// Make a builder for [`EnumeratedValues`]
Expand Down Expand Up @@ -135,7 +130,7 @@ impl EnumeratedValues {
}
self.validate(lvl)
}
/// Validate the [`EnumeratedValues`].
/// Validate the [`EnumeratedValues`]
pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if !lvl.is_disabled() {
if lvl.is_strict() {
Expand All @@ -157,6 +152,13 @@ impl EnumeratedValues {
Ok(())
}
}
/// Validate the [`EnumeratedValues`] recursively.
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
for ev in &self.values {
ev.validate(lvl)?;
}
self.validate(lvl)
}
pub(crate) fn check_range(&self, range: core::ops::Range<u64>) -> Result<(), SvdError> {
for v in self.values.iter() {
v.check_range(&range)?;
Expand Down
18 changes: 18 additions & 0 deletions svd-rs/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{
MaybeArray, ModifiedWriteValues, Name, ReadAction, SvdError, Usage, ValidateLevel,
WriteConstraint,
};
use std::ops::Deref;

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

Ok(())
}
/// Validate the [`FieldInfo`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
for evs in &self.enumerated_values {
evs.validate_all(lvl)?;
}
self.validate(lvl)
}

/// Get bit offset
pub fn bit_offset(&self) -> u32 {
Expand Down Expand Up @@ -377,6 +385,16 @@ impl FieldInfo {
}
}

impl Field {
/// Validate the [`Field`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if let Self::Array(_, dim) = self {
dim.validate(lvl)?;
}
self.deref().validate_all(lvl)
}
}

impl Name for FieldInfo {
fn name(&self) -> &str {
&self.name
Expand Down
32 changes: 31 additions & 1 deletion svd-rs/src/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::{
AddressBlock, BuildError, Cluster, Description, DimElement, EmptyToNone, Interrupt, MaybeArray,
Name, Register, RegisterCluster, RegisterProperties, SvdError, ValidateLevel,
};
use std::ops::Deref;

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

/// Validate the [`Peripheral`]
/// Validate the [`PeripheralInfo`]
pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if !lvl.is_disabled() {
// TODO
Expand All @@ -388,6 +389,25 @@ impl PeripheralInfo {
}
Ok(())
}
/// Validate the [`PeripheralInfo`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if let Some(abs) = self.address_block.as_ref() {
for ab in abs {
ab.validate(lvl)?;
}
}
for i in &self.interrupt {
i.validate(lvl)?;
}
self.default_register_properties.validate(lvl)?;
for r in self.registers() {
r.validate_all(lvl)?;
}
for c in self.clusters() {
c.validate_all(lvl)?;
}
self.validate(lvl)
}

/// Returns iterator over child registers
pub fn registers(&self) -> RegisterIter {
Expand Down Expand Up @@ -492,6 +512,16 @@ impl PeripheralInfo {
}
}

impl Peripheral {
/// Validate the [`Peripheral`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if let Self::Array(_, dim) = self {
dim.validate(lvl)?;
}
self.deref().validate_all(lvl)
}
}

impl Name for PeripheralInfo {
fn name(&self) -> &str {
&self.name
Expand Down
19 changes: 19 additions & 0 deletions svd-rs/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{
ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel,
WriteConstraint,
};
use std::ops::Deref;

/// A single register or array of registers. A register is a named, programmable resource that belongs to a [peripheral](crate::Peripheral).
pub type Register = MaybeArray<RegisterInfo>;
Expand Down Expand Up @@ -358,6 +359,14 @@ impl RegisterInfo {
}
Ok(())
}
/// Validate the [`RegisterInfo`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
self.properties.validate(lvl)?;
for f in self.fields() {
f.validate_all(lvl)?;
}
self.validate(lvl)
}

/// Returns iterator over child fields
pub fn fields(&self) -> std::slice::Iter<Field> {
Expand Down Expand Up @@ -386,6 +395,16 @@ impl RegisterInfo {
}
}

impl Register {
/// Validate the [`Register`] recursively
pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> {
if let Self::Array(_, dim) = self {
dim.validate(lvl)?;
}
self.deref().validate_all(lvl)
}
}

impl Name for RegisterInfo {
fn name(&self) -> &str {
&self.name
Expand Down

0 comments on commit 8c20d17

Please sign in to comment.