Skip to content

Commit 24ecc6d

Browse files
committed
Working on encode functions
Trying out merge extension for non-element objects
1 parent 875bfea commit 24ecc6d

File tree

5 files changed

+109
-14
lines changed

5 files changed

+109
-14
lines changed

src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ trait ElementExt {
6464
fn get_child_u32(&self, n: &str) -> Result<u32, SVDError>;
6565
fn get_child_bool(&self, n: &str) -> Result<bool, SVDError>;
6666

67+
fn merge(&self, n: &Self) -> Self;
68+
6769
fn debug(&self);
6870
}
6971

@@ -120,6 +122,15 @@ impl ElementExt for Element {
120122
BoolParse::parse(s)
121123
}
122124

125+
// Merges the children of two elements, maintaining the name and description of the first
126+
fn merge(&self, r: &Self) -> Self {
127+
let mut n = self.clone();
128+
for c in &r.children {
129+
n.children.push(c.clone());
130+
}
131+
n
132+
}
133+
123134
fn debug(&self) {
124135
println!("<{}>", self.name);
125136
for c in &self.children {

src/parse.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,13 @@ impl Parse for DimIndex {
5555
}
5656
}
5757
}
58+
59+
//TODO: encode for DimIndex
60+
61+
5862
/// Parses an optional child element with the provided name and Parse function
5963
/// Returns an none if the child doesn't exist, Ok(Some(e)) if parsing succeeds,
6064
/// and Err() if parsing fails.
61-
/// TODO: suspect we should be able to use the Parse trait here
6265
pub fn optional<'a, T>(n: &str, e: &'a Element) -> Result<Option<T::Object>, SVDError>
6366
where T: Parse<Error = SVDError>
6467
{

src/svd/cluster.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
use std::ops::Deref;
33
use xmltree::Element;
44

5+
use ElementExt;
6+
57
use types::{Parse, Encode};
68
use error::*;
79
use ::svd::clusterinfo::ClusterInfo;
@@ -33,12 +35,17 @@ impl Parse for Cluster {
3335
let info = ClusterInfo::parse(tree)?;
3436

3537
if tree.get_child("dimIncrement").is_some() {
36-
// TODO: s/assert/errors/g
3738
let array_info = RegisterClusterArrayInfo::parse(tree)?;
38-
assert!(info.name.contains("%s"));
39+
if !info.name.contains("%s") {
40+
// TODO: replace with real error
41+
return Err(SVDError::from(SVDErrorKind::Other("Cluster name invalid".to_string())));
42+
}
3943

4044
if let Some(ref indices) = array_info.dim_index {
41-
assert_eq!(array_info.dim as usize, indices.len())
45+
if array_info.dim as usize != indices.len() {
46+
// TODO: replace with real error
47+
return Err(SVDError::from(SVDErrorKind::Other("Cluster index length mismatch".to_string())));
48+
}
4249
}
4350

4451
Ok(Cluster::Array(info, array_info))
@@ -52,7 +59,18 @@ impl Encode for Cluster {
5259
type Error = SVDError;
5360
// TODO: support Cluster encoding
5461
fn encode(&self) -> Result<Element, SVDError> {
55-
Err(SVDError::from(SVDErrorKind::EncodeNotImplemented(String::from("RegisterClusterArrayInfo"))))
62+
match self {
63+
Cluster::Single(i) => {
64+
let mut e = i.encode()?;
65+
Ok(e)
66+
},
67+
Cluster::Array(i, a) => {
68+
let mut e = i.encode()?;
69+
e = e.merge(&a.encode()?);
70+
Ok(e)
71+
}
72+
}
73+
5674
}
5775
}
5876

src/svd/clusterinfo.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ElementExt;
66
use types::{Parse, Encode, new_element};
77
use parse;
88

9-
use ::error::{SVDError, SVDErrorKind};
9+
use ::error::{SVDError};
1010
use ::svd::access::Access;
1111
use ::svd::registercluster::RegisterCluster;
1212

@@ -60,10 +60,37 @@ impl Parse for ClusterInfo {
6060
impl Encode for ClusterInfo {
6161
type Error = SVDError;
6262
fn encode(&self) -> Result<Element, SVDError> {
63-
// TODO: support ClusterInfo encoding
64-
let _ = new_element("fake", None);
63+
let mut e = new_element("cluster", None);
6564

66-
Err(SVDError::from(SVDErrorKind::EncodeNotImplemented(String::from("RegisterClusterArrayInfo"))))
65+
e.children.push(new_element("description", Some(self.description.clone())));
66+
67+
if let Some(ref v) = self.header_struct_name {
68+
e.children.push(new_element("headerStructName", Some(v.clone())));
69+
}
70+
71+
e.children.push(new_element("addressOffset", Some(format!("{}", self.address_offset))));
72+
73+
if let Some(ref v) = self.size {
74+
e.children.push(new_element("size", Some(format!("{}", v))));
75+
}
76+
77+
if let Some(ref v) = self.access {
78+
e.children.push(v.encode()?);
79+
}
80+
81+
if let Some(ref v) = self.reset_value {
82+
e.children.push(new_element("resetValue", Some(format!("{}", v))));
83+
}
84+
85+
if let Some(ref v) = self.reset_mask {
86+
e.children.push(new_element("resetMask", Some(format!("{}", v))));
87+
}
88+
89+
for c in &self.children {
90+
e.children.push(c.encode()?);
91+
}
92+
93+
Ok(e)
6794
}
6895
}
6996

src/svd/registerclusterarrayinfo.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ use parse;
55
use types::{Parse, Encode, new_element};
66
use ElementExt;
77

8-
use ::error::{SVDError, SVDErrorKind};
8+
use ::error::{SVDError};
99

1010
#[derive(Clone, Debug, PartialEq)]
1111
pub struct RegisterClusterArrayInfo {
1212
pub dim: u32,
1313
pub dim_increment: u32,
1414
pub dim_index: Option<Vec<String>>,
15+
// Reserve the right to add more fields to this struct
16+
_extensible: (),
1517
}
1618

1719
impl Parse for RegisterClusterArrayInfo {
@@ -23,18 +25,52 @@ impl Parse for RegisterClusterArrayInfo {
2325
dim: tree.get_child_u32("dim")?,
2426
dim_increment: tree.get_child_u32("dimIncrement")?,
2527
dim_index: parse::optional::<parse::DimIndex>("dimIndex", tree)?,
28+
_extensible: (),
2629
})
2730
}
2831
}
2932

3033
impl Encode for RegisterClusterArrayInfo {
3134
type Error = SVDError;
35+
3236
fn encode(&self) -> Result<Element, SVDError> {
33-
// TODO: support RegisterClusterArrayInfo encoding
34-
let _ = new_element("fake", None);
37+
let mut e = new_element("registerClusterArrayInfo", None);
38+
39+
e.children.push(new_element("dim", Some(format!("{}", self.dim))));
40+
e.children.push(new_element("dimIncrement", Some(format!("{}", self.dim_increment))));
3541

36-
Err(SVDError::from(SVDErrorKind::EncodeNotImplemented(String::from("RegisterClusterArrayInfo"))))
42+
if let Some(ref di) = self.dim_index {
43+
//TODO: this should be a join, but I don't have docs rn
44+
e.children.push(new_element("dimIndex", Some(format!("{},{}", di[0], di[1]))));
45+
}
46+
47+
Ok(e)
3748
}
3849
}
3950

40-
//TODO: test RegisterClusterArrayInfo encode and decode
51+
52+
#[cfg(test)]
53+
mod tests {
54+
use super::*;
55+
use types::test;
56+
57+
#[test]
58+
fn decode_encode() {
59+
let tests = vec![
60+
(RegisterClusterArrayInfo {
61+
dim: 100,
62+
dim_increment: 4,
63+
dim_index: Some(vec!["10".to_owned(), "20".to_owned()]),
64+
_extensible: (),
65+
},
66+
"<registerClusterArrayInfo>
67+
<dim>100</dim>
68+
<dimIncrement>4</dimIncrement>
69+
<dimIndex>10,20</dimIndex>
70+
</registerClusterArrayInfo>
71+
")
72+
];
73+
74+
test::<RegisterClusterArrayInfo>(&tests[..]);
75+
}
76+
}

0 commit comments

Comments
 (0)