Skip to content

Commit 8303482

Browse files
committed
SingleArray & Name trait
1 parent 4916573 commit 8303482

14 files changed

+186
-399
lines changed

svd-rs/CHANGELOG.md

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

88
## Unreleased
99

10+
- Use generic `SingleArray` enum for types which can be either collected into SVD arrays or have only one instance
11+
- `Name` trait for structures that has `name` field
12+
- improves in iterators
13+
- `get_enumerated_values` by usage
14+
1015
## [v0.12.1] - 2021-12-08
1116

1217
- Rename `reg_iter` to `all_registers`,

svd-rs/src/array.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use super::{DimElement, Name};
2+
use core::ops::{Deref, DerefMut};
3+
4+
/// A single SVD instance or array of instances
5+
#[derive(Clone, Debug, PartialEq)]
6+
pub enum SingleArray<T> {
7+
/// A single instance
8+
Single(T),
9+
/// An array of instances
10+
Array(T, DimElement),
11+
}
12+
13+
impl<T> Deref for SingleArray<T> {
14+
type Target = T;
15+
16+
fn deref(&self) -> &T {
17+
match self {
18+
Self::Single(info) => info,
19+
Self::Array(info, _) => info,
20+
}
21+
}
22+
}
23+
24+
impl<T> DerefMut for SingleArray<T> {
25+
fn deref_mut(&mut self) -> &mut T {
26+
match self {
27+
Self::Single(info) => info,
28+
Self::Array(info, _) => info,
29+
}
30+
}
31+
}
32+
33+
impl<T> SingleArray<T> {
34+
/// Return `true` if instance is single
35+
pub const fn is_single(&self) -> bool {
36+
matches!(self, Self::Single(_))
37+
}
38+
/// Return `true` if it is an array
39+
pub const fn is_array(&self) -> bool {
40+
matches!(self, Self::Array(_, _))
41+
}
42+
}
43+
44+
impl<T> Name for SingleArray<T>
45+
where
46+
T: Name,
47+
{
48+
fn name(&self) -> &str {
49+
T::name(self)
50+
}
51+
}
52+
53+
#[cfg(feature = "serde")]
54+
mod ser_de {
55+
use super::*;
56+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
57+
58+
#[derive(serde::Serialize)]
59+
struct SerArray<'a, T> {
60+
#[serde(flatten)]
61+
dim: &'a DimElement,
62+
#[serde(flatten)]
63+
info: &'a T,
64+
}
65+
66+
#[derive(serde::Deserialize)]
67+
struct DeserArray<T> {
68+
#[serde(flatten, default)]
69+
dim: Option<DimElement>,
70+
#[serde(flatten)]
71+
info: T,
72+
}
73+
74+
impl<T> Serialize for SingleArray<T>
75+
where
76+
T: Serialize,
77+
{
78+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
79+
where
80+
S: Serializer,
81+
{
82+
match self {
83+
Self::Single(info) => info.serialize(serializer),
84+
Self::Array(info, dim) => SerArray::<T> { dim, info }.serialize(serializer),
85+
}
86+
}
87+
}
88+
89+
impl<'de, T> Deserialize<'de> for SingleArray<T>
90+
where
91+
T: Deserialize<'de>,
92+
{
93+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
94+
where
95+
D: Deserializer<'de>,
96+
{
97+
let DeserArray { dim, info } = DeserArray::<T>::deserialize(deserializer)?;
98+
if let Some(dim) = dim {
99+
Ok(Self::Array(info, dim))
100+
} else {
101+
Ok(Self::Single(info))
102+
}
103+
}
104+
}
105+
}

svd-rs/src/cluster.rs

Lines changed: 2 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,4 @@
1-
use core::ops::{Deref, DerefMut};
2-
use std::borrow::Cow;
3-
4-
use super::{ClusterInfo, DimElement};
1+
use super::{array::SingleArray, ClusterInfo};
52

63
/// Cluster describes a sequence of neighboring registers within a peripheral.
7-
#[derive(Clone, Debug, PartialEq)]
8-
pub enum Cluster {
9-
/// A single cluster, without any dimension.
10-
Single(ClusterInfo),
11-
/// A cluster array
12-
Array(ClusterInfo, DimElement),
13-
}
14-
15-
impl Deref for Cluster {
16-
type Target = ClusterInfo;
17-
18-
fn deref(&self) -> &ClusterInfo {
19-
match self {
20-
Self::Single(info) => info,
21-
Self::Array(info, _) => info,
22-
}
23-
}
24-
}
25-
26-
impl DerefMut for Cluster {
27-
fn deref_mut(&mut self) -> &mut ClusterInfo {
28-
match self {
29-
Self::Single(info) => info,
30-
Self::Array(info, _) => info,
31-
}
32-
}
33-
}
34-
35-
impl Cluster {
36-
/// Return `true` if cluster instance is single
37-
pub const fn is_single(&self) -> bool {
38-
matches!(self, Self::Single(_))
39-
}
40-
/// Return `true` if it is cluster array
41-
pub const fn is_array(&self) -> bool {
42-
matches!(self, Self::Array(_, _))
43-
}
44-
/// Returns list of register or register array names
45-
pub fn names(&self) -> Vec<Cow<str>> {
46-
match self {
47-
Self::Single(info) => vec![info.name.as_str().into()],
48-
Self::Array(info, dim) => dim
49-
.indexes()
50-
.map(|i| info.name.replace("[%s]", &i).replace("%s", &i).into())
51-
.collect(),
52-
}
53-
}
54-
/// Returns list of register or register array address_offsets
55-
pub fn address_offsets(&self) -> Vec<u32> {
56-
match self {
57-
Self::Single(info) => vec![info.address_offset],
58-
Self::Array(info, dim) => (0..dim.dim)
59-
.map(|n| info.address_offset + n * dim.dim_increment)
60-
.collect(),
61-
}
62-
}
63-
}
64-
65-
#[cfg(feature = "serde")]
66-
mod ser_de {
67-
use super::*;
68-
use crate::{DeserArray, SerArray};
69-
use serde::{Deserialize, Deserializer, Serialize, Serializer};
70-
71-
impl Serialize for Cluster {
72-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73-
where
74-
S: Serializer,
75-
{
76-
match self {
77-
Self::Single(info) => info.serialize(serializer),
78-
Self::Array(info, dim) => SerArray { dim, info }.serialize(serializer),
79-
}
80-
}
81-
}
82-
83-
impl<'de> Deserialize<'de> for Cluster {
84-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85-
where
86-
D: Deserializer<'de>,
87-
{
88-
let DeserArray { dim, info } = DeserArray::<ClusterInfo>::deserialize(deserializer)?;
89-
if let Some(dim) = dim {
90-
Ok(info.array(dim))
91-
} else {
92-
Ok(info.single())
93-
}
94-
}
95-
}
96-
}
4+
pub type Cluster = SingleArray<ClusterInfo>;

svd-rs/src/clusterinfo.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use super::{
33
AllRegistersIter, AllRegistersIterMut, ClusterIter, ClusterIterMut, RegisterIter,
44
RegisterIterMut,
55
},
6-
BuildError, Cluster, DimElement, EmptyToNone, Register, RegisterCluster, RegisterProperties,
7-
SvdError, ValidateLevel,
6+
BuildError, Cluster, DimElement, EmptyToNone, Name, Register, RegisterCluster,
7+
RegisterProperties, SvdError, ValidateLevel,
88
};
99

1010
/// Errors from [`ClusterInfo::validate`]
@@ -303,3 +303,9 @@ impl ClusterInfo {
303303
self.clusters_mut().find(|f| f.name == name)
304304
}
305305
}
306+
307+
impl Name for ClusterInfo {
308+
fn name(&self) -> &str {
309+
&self.name
310+
}
311+
}

svd-rs/src/device.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{
2-
BuildError, Cpu, EmptyToNone, Peripheral, RegisterProperties, SvdError, ValidateLevel,
2+
BuildError, Cpu, EmptyToNone, Name, Peripheral, RegisterProperties, SvdError, ValidateLevel,
33
};
44

55
/// Errors for [`Device::validate`]
@@ -236,3 +236,9 @@ impl Device {
236236
self.peripherals.iter_mut().find(|f| f.name == name)
237237
}
238238
}
239+
240+
impl Name for Device {
241+
fn name(&self) -> &str {
242+
&self.name
243+
}
244+
}

svd-rs/src/enumeratedvalue.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{BuildError, EmptyToNone, SvdError, ValidateLevel};
1+
use super::{BuildError, EmptyToNone, Name, SvdError, ValidateLevel};
22

33
/// Describes a single entry in the enumeration.
44
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
@@ -146,3 +146,9 @@ impl EnumeratedValue {
146146
}
147147
}
148148
}
149+
150+
impl Name for EnumeratedValue {
151+
fn name(&self) -> &str {
152+
&self.name
153+
}
154+
}

svd-rs/src/enumeratedvalues.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ impl EnumeratedValues {
156156
self.usage.unwrap_or_default()
157157
}
158158

159-
/// Get enumeratedValue by name
159+
/// Get `enumeratedValue` by name
160160
pub fn get_value(&self, name: &str) -> Option<&EnumeratedValue> {
161161
self.values.iter().find(|e| e.name == name)
162162
}
163163

164-
/// Get mutable enumeratedValue by name
164+
/// Get mutable `enumeratedValue` by name
165165
pub fn get_mut_value(&mut self, name: &str) -> Option<&mut EnumeratedValue> {
166166
self.values.iter_mut().find(|e| e.name == name)
167167
}

svd-rs/src/field.rs

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,4 @@
1-
use super::{DimElement, FieldInfo};
2-
use core::ops::{Deref, DerefMut};
3-
use std::borrow::Cow;
1+
use super::{array::SingleArray, FieldInfo};
42

53
/// Describes a field or fields of a [register](crate::RegisterInfo).
6-
#[derive(Clone, Debug, PartialEq)]
7-
pub enum Field {
8-
/// A single field.
9-
Single(FieldInfo),
10-
/// A field array.
11-
Array(FieldInfo, DimElement),
12-
}
13-
14-
impl Deref for Field {
15-
type Target = FieldInfo;
16-
17-
fn deref(&self) -> &FieldInfo {
18-
match self {
19-
Self::Single(info) => info,
20-
Self::Array(info, _) => info,
21-
}
22-
}
23-
}
24-
25-
impl DerefMut for Field {
26-
fn deref_mut(&mut self) -> &mut FieldInfo {
27-
match self {
28-
Self::Single(info) => info,
29-
Self::Array(info, _) => info,
30-
}
31-
}
32-
}
33-
34-
impl Field {
35-
/// Return `true` if field instance is single
36-
pub const fn is_single(&self) -> bool {
37-
matches!(self, Self::Single(_))
38-
}
39-
/// Return `true` if it is field array
40-
pub const fn is_array(&self) -> bool {
41-
matches!(self, Self::Array(_, _))
42-
}
43-
/// Returns list of register or register array names
44-
pub fn names(&self) -> Vec<Cow<str>> {
45-
match self {
46-
Self::Single(info) => vec![info.name.as_str().into()],
47-
Self::Array(info, dim) => dim
48-
.indexes()
49-
.map(|i| info.name.replace("[%s]", &i).replace("%s", &i).into())
50-
.collect(),
51-
}
52-
}
53-
/// Returns list of register or register array bit offsets
54-
pub fn bit_offsets(&self) -> Vec<u32> {
55-
match self {
56-
Self::Single(info) => vec![info.bit_offset()],
57-
Self::Array(info, dim) => (0..dim.dim)
58-
.map(|n| info.bit_offset() + n * dim.dim_increment)
59-
.collect(),
60-
}
61-
}
62-
}
63-
64-
#[cfg(feature = "serde")]
65-
mod ser_de {
66-
use super::*;
67-
use crate::{DeserArray, SerArray};
68-
use serde::{Deserialize, Deserializer, Serialize, Serializer};
69-
70-
impl Serialize for Field {
71-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
72-
where
73-
S: Serializer,
74-
{
75-
match self {
76-
Self::Single(info) => info.serialize(serializer),
77-
Self::Array(info, dim) => SerArray { dim, info }.serialize(serializer),
78-
}
79-
}
80-
}
81-
82-
impl<'de> Deserialize<'de> for Field {
83-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
84-
where
85-
D: Deserializer<'de>,
86-
{
87-
let DeserArray { dim, info } = DeserArray::<FieldInfo>::deserialize(deserializer)?;
88-
if let Some(dim) = dim {
89-
Ok(info.array(dim))
90-
} else {
91-
Ok(info.single())
92-
}
93-
}
94-
}
95-
}
4+
pub type Field = SingleArray<FieldInfo>;

0 commit comments

Comments
 (0)