Skip to content

Commit 5764bba

Browse files
committed
deserialize dimIndex string
1 parent d0839b7 commit 5764bba

File tree

3 files changed

+57
-32
lines changed

3 files changed

+57
-32
lines changed

svd-parser/src/dimelement.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::types::DimIndex;
21
use super::*;
32
use crate::svd::{DimArrayIndex, DimElement, EnumeratedValue};
43

@@ -44,3 +43,16 @@ impl Parse for DimArrayIndex {
4443
})
4544
}
4645
}
46+
47+
struct DimIndex;
48+
49+
impl Parse for DimIndex {
50+
type Object = Vec<String>;
51+
type Error = SVDErrorAt;
52+
type Config = Config;
53+
54+
fn parse(tree: &Node, _config: &Self::Config) -> Result<Vec<String>, Self::Error> {
55+
DimElement::parse_indexes(tree.get_text()?)
56+
.ok_or_else(|| SVDError::DimIndexParse.at(tree.id()))
57+
}
58+
}

svd-parser/src/types.rs

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use roxmltree::Node;
55

6-
use super::{Config, ElementExt, Parse, SVDError, SVDErrorAt};
6+
use super::{ElementExt, Parse, SVDError, SVDErrorAt};
77

88
impl Parse for u32 {
99
type Object = u32;
@@ -84,32 +84,3 @@ impl Parse for BoolParse {
8484
}
8585
}
8686
}
87-
88-
pub struct DimIndex;
89-
90-
impl Parse for DimIndex {
91-
type Object = Vec<String>;
92-
type Error = SVDErrorAt;
93-
type Config = Config;
94-
95-
fn parse(tree: &Node, _config: &Self::Config) -> Result<Vec<String>, Self::Error> {
96-
let text = tree.get_text()?;
97-
if text.contains('-') {
98-
let mut parts = text.splitn(2, '-');
99-
let start = parts
100-
.next()
101-
.ok_or_else(|| SVDError::DimIndexParse.at(tree.id()))?
102-
.parse::<u32>()
103-
.map_err(|e| SVDError::from(e).at(tree.id()))?;
104-
let end = parts
105-
.next()
106-
.ok_or_else(|| SVDError::DimIndexParse.at(tree.id()))?
107-
.parse::<u32>()
108-
.map_err(|e| SVDError::from(e).at(tree.id()))?;
109-
110-
Ok((start..=end).map(|i| i.to_string()).collect())
111-
} else {
112-
Ok(text.split(',').map(|s| s.to_string()).collect())
113-
}
114-
}
115-
}

svd-rs/src/dimelement.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ pub struct DimElement {
2121
/// By default, <dimIndex> is a value starting with 0
2222
#[cfg_attr(
2323
feature = "serde",
24-
serde(default, skip_serializing_if = "Option::is_none")
24+
serde(
25+
deserialize_with = "ser_de::deserialize_dim_index",
26+
skip_serializing_if = "Option::is_none"
27+
)
2528
)]
2629
pub dim_index: Option<Vec<String>>,
2730

@@ -137,6 +140,19 @@ impl DimElement {
137140
pub fn builder() -> DimElementBuilder {
138141
DimElementBuilder::default()
139142
}
143+
144+
/// Get array of indexes from string
145+
pub fn parse_indexes(text: &str) -> Option<Vec<String>> {
146+
if text.contains('-') {
147+
let mut parts = text.splitn(2, '-');
148+
let start = parts.next()?.parse::<u32>().ok()?;
149+
let end = parts.next()?.parse::<u32>().ok()?;
150+
151+
Some((start..=end).map(|i| i.to_string()).collect())
152+
} else {
153+
Some(text.split(',').map(|s| s.to_string()).collect())
154+
}
155+
}
140156
/// Try to represent [`DimElement`] as range of integer indexes
141157
pub fn indexes_as_range(&self) -> Option<RangeInclusive<u32>> {
142158
let mut integers = Vec::with_capacity(self.dim as usize);
@@ -223,3 +239,29 @@ impl<'a> Iterator for Indexes<'a> {
223239
}
224240
}
225241
}
242+
243+
#[cfg(feature = "serde")]
244+
mod ser_de {
245+
use super::*;
246+
use serde::{de, Deserialize, Deserializer};
247+
#[derive(serde::Serialize, serde::Deserialize)]
248+
#[serde(untagged)]
249+
enum DimIndex {
250+
Array(Vec<String>),
251+
String(String),
252+
}
253+
254+
pub fn deserialize_dim_index<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
255+
where
256+
D: Deserializer<'de>,
257+
{
258+
Ok(match Option::<DimIndex>::deserialize(deserializer)? {
259+
None => None,
260+
Some(DimIndex::Array(a)) => Some(a),
261+
Some(DimIndex::String(s)) => Some(
262+
DimElement::parse_indexes(&s)
263+
.ok_or_else(|| de::Error::custom("Failed to deserialize dimIndex"))?,
264+
),
265+
})
266+
}
267+
}

0 commit comments

Comments
 (0)