use super::{BuildError, Protection, SvdError, ValidateLevel};
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct AddressBlock {
pub offset: u32,
pub size: u32,
pub usage: AddressBlockUsage,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub protection: Option<Protection>,
}
#[cfg_attr(
feature = "serde",
derive(serde::Deserialize, serde::Serialize),
serde(rename_all = "kebab-case")
)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum AddressBlockUsage {
Registers,
Buffer,
Reserved,
}
impl Default for AddressBlockUsage {
fn default() -> Self {
Self::Registers
}
}
impl AddressBlockUsage {
pub fn parse_str(s: &str) -> Option<Self> {
match s {
"registers" => Some(Self::Registers),
"buffer" => Some(Self::Buffer),
"reserved" => Some(Self::Reserved),
_ => None,
}
}
pub const fn as_str(self) -> &'static str {
match self {
Self::Registers => "registers",
Self::Buffer => "buffer",
Self::Reserved => "reserved",
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AddressBlockBuilder {
offset: Option<u32>,
size: Option<u32>,
usage: Option<AddressBlockUsage>,
protection: Option<Protection>,
}
impl From<AddressBlock> for AddressBlockBuilder {
fn from(d: AddressBlock) -> Self {
Self {
offset: Some(d.offset),
size: Some(d.size),
usage: Some(d.usage),
protection: d.protection,
}
}
}
impl AddressBlockBuilder {
pub fn offset(mut self, value: u32) -> Self {
self.offset = Some(value);
self
}
pub fn size(mut self, value: u32) -> Self {
self.size = Some(value);
self
}
pub fn usage(mut self, value: AddressBlockUsage) -> Self {
self.usage = Some(value);
self
}
pub fn protection(mut self, value: Option<Protection>) -> Self {
self.protection = value;
self
}
pub fn build(self, lvl: ValidateLevel) -> Result<AddressBlock, SvdError> {
let mut de = AddressBlock {
offset: self
.offset
.ok_or_else(|| BuildError::Uninitialized("offset".to_string()))?,
size: self
.size
.ok_or_else(|| BuildError::Uninitialized("size".to_string()))?,
usage: self
.usage
.ok_or_else(|| BuildError::Uninitialized("usage".to_string()))?,
protection: self.protection,
};
if !lvl.is_disabled() {
de.validate(lvl)?;
}
Ok(de)
}
}
impl AddressBlock {
pub fn builder() -> AddressBlockBuilder {
AddressBlockBuilder::default()
}
pub fn modify_from(
&mut self,
builder: AddressBlockBuilder,
lvl: ValidateLevel,
) -> Result<(), SvdError> {
if let Some(offset) = builder.offset {
self.offset = offset;
}
if let Some(size) = builder.size {
self.size = size;
}
if let Some(usage) = builder.usage {
self.usage = usage;
}
if builder.protection.is_some() {
self.protection = builder.protection;
}
if !lvl.is_disabled() {
self.validate(lvl)
} else {
Ok(())
}
}
pub fn validate(&mut self, _lvl: ValidateLevel) -> Result<(), SvdError> {
Ok(())
}
}