|
1 |
| -#[cfg(feature = "unproven")] |
2 |
| -use std::collections::HashMap; |
| 1 | +use core::ops::Deref; |
3 | 2 |
|
4 |
| -use crate::elementext::ElementExt; |
5 |
| -use failure::ResultExt; |
6 | 3 | use xmltree::Element;
|
7 | 4 |
|
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; |
14 | 5 | use crate::types::Parse;
|
15 | 6 |
|
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}; |
20 | 13 |
|
21 | 14 | #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
22 | 15 | #[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 | + } |
34 | 30 | }
|
35 | 31 |
|
36 | 32 | impl Parse for Field {
|
37 | 33 | type Object = Field;
|
38 | 34 | type Error = SVDError;
|
| 35 | + |
39 | 36 | 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)) |
42 | 50 | }
|
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 |
| - }) |
74 | 51 | }
|
75 | 52 | }
|
76 | 53 |
|
77 | 54 | #[cfg(feature = "unproven")]
|
78 | 55 | impl Encode for Field {
|
79 | 56 | 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 |
| - }; |
96 | 57 |
|
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 | + } |
100 | 67 | }
|
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) |
122 | 68 | }
|
123 | 69 | }
|
124 | 70 |
|
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