#![deny(missing_docs)]
pub mod array;
pub use array::MaybeArray;
pub mod endian;
pub use self::endian::Endian;
pub mod cpu;
pub use self::cpu::{Cpu, CpuBuilder};
pub mod interrupt;
pub use self::interrupt::Interrupt;
pub mod access;
pub use self::access::Access;
pub mod bitrange;
pub use self::bitrange::{BitRange, BitRangeType};
pub mod writeconstraint;
pub use self::writeconstraint::{WriteConstraint, WriteConstraintRange};
pub mod usage;
pub use self::usage::Usage;
pub mod enumeratedvalue;
pub use self::enumeratedvalue::{EnumeratedValue, EnumeratedValueBuilder};
pub mod enumeratedvalues;
pub use self::enumeratedvalues::{EnumeratedValues, EnumeratedValuesBuilder};
pub mod field;
pub use self::field::{Field, FieldInfo, FieldInfoBuilder};
pub mod registerproperties;
pub use self::registerproperties::RegisterProperties;
pub mod addressblock;
pub use self::addressblock::{AddressBlock, AddressBlockUsage};
pub mod cluster;
pub use self::cluster::{Cluster, ClusterInfo, ClusterInfoBuilder};
pub mod register;
pub use self::register::{Register, RegisterInfo, RegisterInfoBuilder};
pub mod registercluster;
pub use self::registercluster::RegisterCluster;
pub mod dimelement;
pub use self::dimelement::{DimArrayIndex, DimElement, DimElementBuilder};
pub mod peripheral;
pub use self::peripheral::{Peripheral, PeripheralInfo, PeripheralInfoBuilder};
pub mod device;
pub use self::device::{Device, DeviceBuilder};
pub mod modifiedwritevalues;
pub use self::modifiedwritevalues::ModifiedWriteValues;
pub mod readaction;
pub use self::readaction::ReadAction;
pub mod protection;
pub use self::protection::Protection;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ValidateLevel {
Disabled,
Weak,
Strict,
}
impl Default for ValidateLevel {
fn default() -> Self {
ValidateLevel::Weak
}
}
impl ValidateLevel {
pub fn is_disabled(self) -> bool {
self == ValidateLevel::Disabled
}
pub fn is_weak(self) -> bool {
self != ValidateLevel::Disabled
}
pub fn is_strict(self) -> bool {
self == ValidateLevel::Strict
}
}
#[cfg(feature = "derive-from")]
pub mod derive_from;
#[cfg(feature = "derive-from")]
pub use derive_from::DeriveFrom;
use once_cell::sync::Lazy;
use regex::Regex;
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
pub enum SvdError {
#[error("`Build error: {0}")]
Build(#[from] BuildError),
#[error("`Name check error: {0}")]
Name(#[from] NameError),
#[error("`Device error: {0}")]
Device(#[from] device::Error),
#[error("`Peripheral error: {0}")]
Peripheral(#[from] peripheral::Error),
#[error("`Cluster error: {0}")]
Cluster(#[from] cluster::Error),
#[error("`Register error: {0}")]
Register(#[from] register::Error),
#[error("`Field error: {0}")]
Field(#[from] field::Error),
#[error("`BitRange error: {0}")]
BitRange(#[from] bitrange::Error),
#[error("`EnumeratedValue error: {0}")]
EnumeratedValue(#[from] enumeratedvalue::Error),
#[error("`EnumeratedValues error: {0}")]
EnumeratedValues(#[from] enumeratedvalues::Error),
#[error("`RegisterProperties error: {0}")]
RegisterProperties(#[from] registerproperties::Error),
#[error("`WriteConstraint error: {0}")]
WriteConstraint(#[from] writeconstraint::Error),
}
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
pub enum BuildError {
#[error("`{0}` must be initialized")]
Uninitialized(String),
}
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
pub enum NameError {
#[error("Name `{0}` contains unexpected symbol")]
Invalid(String, String),
}
pub(crate) fn check_name(name: &str, tag: &str) -> Result<(), NameError> {
static PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new("^[_A-Za-z0-9]*$").unwrap());
if PATTERN.is_match(name) {
Ok(())
} else {
Err(NameError::Invalid(name.to_string(), tag.to_string()))
}
}
pub(crate) fn check_dimable_name(name: &str, tag: &str) -> Result<(), NameError> {
static PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new("^(((%s)|(%s)[_A-Za-z]{1}[_A-Za-z0-9]*)|([_A-Za-z]{1}[_A-Za-z0-9]*(\\[%s\\])?)|([_A-Za-z]{1}[_A-Za-z0-9]*(%s)?[_A-Za-z0-9]*))$").unwrap()
});
if PATTERN.is_match(name) {
Ok(())
} else {
Err(NameError::Invalid(name.to_string(), tag.to_string()))
}
}
pub(crate) fn check_derived_name(name: &str, tag: &str) -> Result<(), NameError> {
for x in name.split('.') {
check_dimable_name(x, tag)?
}
Ok(())
}
trait EmptyToNone {
fn empty_to_none(self) -> Self;
}
impl EmptyToNone for Option<String> {
fn empty_to_none(self) -> Self {
self.and_then(|s| if s.is_empty() { None } else { Some(s) })
}
}
impl<T> EmptyToNone for Option<Vec<T>> {
fn empty_to_none(self) -> Self {
self.and_then(|v| if v.is_empty() { None } else { Some(v) })
}
}
pub trait Name {
fn name(&self) -> &str;
}
impl<T> Name for &T
where
T: Name,
{
fn name(&self) -> &str {
T::name(*self)
}
}
impl<T> Name for &mut T
where
T: Name,
{
fn name(&self) -> &str {
T::name(*self)
}
}
pub trait Description {
fn description(&self) -> Option<&str>;
}
impl<T> Description for &T
where
T: Description,
{
fn description(&self) -> Option<&str> {
T::description(*self)
}
}
impl<T> Description for &mut T
where
T: Description,
{
fn description(&self) -> Option<&str> {
T::description(*self)
}
}