Skip to content

Commit 0c00bc2

Browse files
committed
Field arrays
1 parent ddc9799 commit 0c00bc2

File tree

5 files changed

+263
-186
lines changed

5 files changed

+263
-186
lines changed

CHANGELOG.md

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

1010
- [breaking-change] `Defaults` field renamed on `RegisterProperties`
1111
and added into `Peripheral` and `ClusterInfo`
12+
- [breaking-change] `Field` splitted on `Field` enum and `FieldInfo` struct
13+
to support field arrays
1214
- Added `derived_from` into `Field` and `ClusterInfo`
1315
- Updated dependencies, use `Edition 2018`
1416
- Added missing `zeroToToggle`

src/svd/field.rs

Lines changed: 45 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -1,210 +1,71 @@
1-
#[cfg(feature = "unproven")]
2-
use std::collections::HashMap;
1+
use core::ops::Deref;
32

4-
use crate::elementext::ElementExt;
5-
use failure::ResultExt;
63
use xmltree::Element;
74

8-
#[cfg(feature = "unproven")]
9-
use crate::encode::Encode;
10-
use crate::error::*;
11-
#[cfg(feature = "unproven")]
12-
use crate::new_element;
13-
use crate::parse;
145
use crate::types::Parse;
156

16-
use crate::svd::{
17-
access::Access, bitrange::BitRange, enumeratedvalues::EnumeratedValues,
18-
modifiedwritevalues::ModifiedWriteValues, writeconstraint::WriteConstraint,
19-
};
7+
#[cfg(feature = "unproven")]
8+
use crate::elementext::ElementExt;
9+
#[cfg(feature = "unproven")]
10+
use crate::encode::Encode;
11+
use crate::error::SVDError;
12+
use crate::svd::{dimelement::DimElement, fieldinfo::FieldInfo};
2013

2114
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
2215
#[derive(Clone, Debug, PartialEq)]
23-
pub struct Field {
24-
pub name: String,
25-
pub derived_from: Option<String>,
26-
pub description: Option<String>,
27-
pub bit_range: BitRange,
28-
pub access: Option<Access>,
29-
pub enumerated_values: Vec<EnumeratedValues>,
30-
pub write_constraint: Option<WriteConstraint>,
31-
pub modified_write_values: Option<ModifiedWriteValues>,
32-
// Reserve the right to add more fields to this struct
33-
pub(crate) _extensible: (),
16+
pub enum Field {
17+
Single(FieldInfo),
18+
Array(FieldInfo, DimElement),
19+
}
20+
21+
impl Deref for Field {
22+
type Target = FieldInfo;
23+
24+
fn deref(&self) -> &FieldInfo {
25+
match self {
26+
Field::Single(info) => info,
27+
Field::Array(info, _) => info,
28+
}
29+
}
3430
}
3531

3632
impl Parse for Field {
3733
type Object = Field;
3834
type Error = SVDError;
35+
3936
fn parse(tree: &Element) -> Result<Field, SVDError> {
40-
if tree.name != "field" {
41-
return Err(SVDErrorKind::NotExpectedTag(tree.clone(), "field".to_string()).into());
37+
assert_eq!(tree.name, "field");
38+
39+
let info = FieldInfo::parse(tree)?;
40+
41+
if tree.get_child("dimIncrement").is_some() {
42+
let array_info = DimElement::parse(tree)?;
43+
assert!(info.name.contains("%s"));
44+
if let Some(indices) = &array_info.dim_index {
45+
assert_eq!(array_info.dim as usize, indices.len())
46+
}
47+
Ok(Field::Array(info, array_info))
48+
} else {
49+
Ok(Field::Single(info))
4250
}
43-
let name = tree.get_child_text("name")?;
44-
Field::_parse(tree, name.clone())
45-
.context(SVDErrorKind::Other(format!("In field `{}`", name)))
46-
.map_err(|e| e.into())
47-
}
48-
}
49-
50-
impl Field {
51-
fn _parse(tree: &Element, name: String) -> Result<Field, SVDError> {
52-
Ok(Field {
53-
name,
54-
derived_from: tree.attributes.get("derivedFrom").map(|s| s.to_owned()),
55-
description: tree.get_child_text_opt("description")?,
56-
bit_range: BitRange::parse(tree)?,
57-
access: parse::optional::<Access>("access", tree)?,
58-
enumerated_values: {
59-
let values: Result<Vec<_>, _> = tree
60-
.children
61-
.iter()
62-
.filter(|t| t.name == "enumeratedValues")
63-
.map(EnumeratedValues::parse)
64-
.collect();
65-
values?
66-
},
67-
write_constraint: parse::optional::<WriteConstraint>("writeConstraint", tree)?,
68-
modified_write_values: parse::optional::<ModifiedWriteValues>(
69-
"modifiedWriteValues",
70-
tree,
71-
)?,
72-
_extensible: (),
73-
})
7451
}
7552
}
7653

7754
#[cfg(feature = "unproven")]
7855
impl Encode for Field {
7956
type Error = SVDError;
80-
fn encode(&self) -> Result<Element, SVDError> {
81-
let mut children = vec![new_element("name", Some(self.name.clone()))];
82-
83-
if let Some(description) = &self.description {
84-
children.push(new_element("description", Some(description.clone())))
85-
}
86-
87-
let mut elem = Element {
88-
prefix: None,
89-
namespace: None,
90-
namespaces: None,
91-
name: String::from("field"),
92-
attributes: HashMap::new(),
93-
children,
94-
text: None,
95-
};
9657

97-
if let Some(v) = &self.derived_from {
98-
elem.attributes
99-
.insert(String::from("derivedFrom"), format!("{}", v));
58+
fn encode(&self) -> Result<Element, SVDError> {
59+
match self {
60+
Field::Single(info) => info.encode(),
61+
Field::Array(info, array_info) => {
62+
// TODO: is this correct? probably not, need tests
63+
let base = info.encode()?;
64+
base.merge(&array_info.encode()?);
65+
Ok(base)
66+
}
10067
}
101-
102-
// Add bit range
103-
elem.children.append(&mut self.bit_range.encode()?);
104-
105-
if let Some(v) = &self.access {
106-
elem.children.push(v.encode()?);
107-
};
108-
109-
let enumerated_values: Result<Vec<Element>, SVDError> =
110-
self.enumerated_values.iter().map(|v| v.encode()).collect();
111-
elem.children.append(&mut enumerated_values?);
112-
113-
if let Some(v) = &self.write_constraint {
114-
elem.children.push(v.encode()?);
115-
};
116-
117-
if let Some(v) = &self.modified_write_values {
118-
elem.children.push(v.encode()?);
119-
};
120-
121-
Ok(elem)
12268
}
12369
}
12470

125-
#[cfg(test)]
126-
#[cfg(feature = "unproven")]
127-
mod tests {
128-
use super::*;
129-
use crate::run_test;
130-
use crate::svd::{bitrange::BitRangeType, enumeratedvalue::EnumeratedValue};
131-
132-
#[test]
133-
fn decode_encode() {
134-
let tests = vec![
135-
(
136-
Field {
137-
name: String::from("MODE"),
138-
derived_from: None,
139-
description: Some(String::from("Read Mode")),
140-
bit_range: BitRange {
141-
offset: 24,
142-
width: 2,
143-
range_type: BitRangeType::OffsetWidth,
144-
},
145-
access: Some(Access::ReadWrite),
146-
enumerated_values: vec![EnumeratedValues {
147-
name: None,
148-
usage: None,
149-
derived_from: None,
150-
values: vec![EnumeratedValue {
151-
name: String::from("WS0"),
152-
description: Some(String::from(
153-
"Zero wait-states inserted in fetch or read transfers",
154-
)),
155-
value: Some(0),
156-
is_default: None,
157-
_extensible: (),
158-
}],
159-
_extensible: (),
160-
}],
161-
write_constraint: None,
162-
modified_write_values: None,
163-
_extensible: (),
164-
},
165-
"
166-
<field>
167-
<name>MODE</name>
168-
<description>Read Mode</description>
169-
<bitOffset>24</bitOffset>
170-
<bitWidth>2</bitWidth>
171-
<access>read-write</access>
172-
<enumeratedValues>
173-
<enumeratedValue>
174-
<name>WS0</name>
175-
<description>Zero wait-states inserted in fetch or read transfers</description>
176-
<value>0x00000000</value>
177-
</enumeratedValue>
178-
</enumeratedValues>
179-
</field>
180-
",
181-
),
182-
(
183-
Field {
184-
name: String::from("MODE"),
185-
derived_from: Some(String::from("other field")),
186-
description: None,
187-
bit_range: BitRange {
188-
offset: 24,
189-
width: 2,
190-
range_type: BitRangeType::OffsetWidth,
191-
},
192-
access: None,
193-
enumerated_values: vec![],
194-
write_constraint: None,
195-
modified_write_values: None,
196-
_extensible: (),
197-
},
198-
"
199-
<field derivedFrom=\"other field\">
200-
<name>MODE</name>
201-
<bitOffset>24</bitOffset>
202-
<bitWidth>2</bitWidth>
203-
</field>
204-
",
205-
),
206-
];
207-
208-
run_test::<Field>(&tests[..]);
209-
}
210-
}
71+
// TODO: add Field encode and decode tests

0 commit comments

Comments
 (0)