diff --git a/src/atdf/field.rs b/src/atdf/field.rs index a867574..f7ff149 100644 --- a/src/atdf/field.rs +++ b/src/atdf/field.rs @@ -6,15 +6,14 @@ use crate::ElementExt; pub fn parse( bitfield_el: &xmltree::Element, value_groups: &atdf::values::ValueGroups, - mode_name: Option, + mode_name: Option<&str>, ) -> crate::Result { debug_assert!(bitfield_el.name == "bitfield"); - let name; - if let Some(mode) = mode_name { - name = format!("{}_{}", mode, bitfield_el.attr("name")?.clone()); + let name: String = if let Some(mode) = mode_name { + format!("{}_{}", mode, bitfield_el.attr("name")?) } else { - name = bitfield_el.attr("name")?.clone(); - } + bitfield_el.attr("name")?.clone() + }; let description = bitfield_el .attributes .get("caption") diff --git a/src/atdf/register.rs b/src/atdf/register.rs index 5aba522..df1a819 100644 --- a/src/atdf/register.rs +++ b/src/atdf/register.rs @@ -4,6 +4,19 @@ use crate::util; use crate::ElementExt; use std::collections::BTreeMap; +fn field_map_from_bitfield_children( + el: &xmltree::Element, + values: &atdf::values::ValueGroups, + mode_name: Option<&str>, +) -> crate::Result> { + el.children + .iter() + .filter_map(|node| node.as_element().filter(|e| e.name == "bitfield")) + .map(|e| atdf::field::parse(e, values, mode_name)) + .map(|r| r.map(|f| (f.name.clone(), f))) + .collect::, _>>() +} + pub fn parse( el: &xmltree::Element, offset: usize, @@ -35,32 +48,27 @@ pub fn parse( chip::AccessMode::ReadWrite }; - let mut fields: BTreeMap = el - .children - .iter() - .filter_map(|node| node.as_element().filter(|e| e.name == "bitfield")) - .map(|e| atdf::field::parse(e, values, None)) - .map(|r| r.map(|f| (f.name.clone(), f))) - .collect::, _>>()?; + // get bitfield under register + let mut fields: BTreeMap = + field_map_from_bitfield_children(el, values, None)?; - let modes = el - .children + // get bitfield under register.mode + el.children .iter() - .filter_map(|mode| mode.as_element().filter(|m| m.name == "mode")) - .into_iter(); - for mode in modes { - if let Some(mode_name) = mode.attributes.get("name").cloned() { - let res = mode - .children - .clone() - .into_iter() - .filter_map(|el| el.as_element().filter(|e| e.name == "bitfield").cloned()) - .map(|e| atdf::field::parse(&e, values, Some(mode_name.clone()))) - .map(|r| r.map(|f| (f.name.clone(), f))) - .collect::, _>>()?; - fields.append(&mut res.clone()); - } - } + .filter_map(|mode| { + mode.as_element() + .filter(|m| m.name == "mode") + .and_then(|m| m.attributes.get("name").map(|mode_name| (mode_name, m))) + }) + .try_for_each(|(mode_name, el)| { + fields.append(&mut field_map_from_bitfield_children( + el, + values, + Some(mode_name), + )?); + crate::Result::Ok(()) + })?; + Ok(chip::Register { name, description,