1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use super::*;
use crate::svd::{DimArrayIndex, DimElement, EnumeratedValue};

impl Parse for DimElement {
    type Object = Self;
    type Error = SVDErrorAt;
    type Config = Config;

    fn parse(tree: &Node, config: &Self::Config) -> Result<Self, Self::Error> {
        DimElement::builder()
            .dim(tree.get_child_u32("dim")?)
            .dim_increment(tree.get_child_u32("dimIncrement")?)
            .dim_index(optional::<DimIndex>("dimIndex", tree, config)?)
            .dim_name(tree.get_child_text_opt("dimName")?)
            .dim_array_index(optional::<DimArrayIndex>("dimArrayIndex", tree, config)?)
            .build(config.validate_level)
            .map_err(|e| SVDError::from(e).at(tree.id()))
    }
}

impl Parse for DimArrayIndex {
    type Object = Self;
    type Error = SVDErrorAt;
    type Config = Config;

    fn parse(tree: &Node, config: &Self::Config) -> Result<Self, Self::Error> {
        Ok(Self {
            header_enum_name: tree.get_child_text_opt("headerEnumName")?,
            values: {
                let values: Result<Vec<_>, _> = tree
                    .children()
                    .filter(|t| t.is_element() && !matches!(t.tag_name().name(), "headerEnumName"))
                    .map(|t| {
                        if t.has_tag_name("enumeratedValue") {
                            EnumeratedValue::parse(&t, config)
                        } else {
                            Err(SVDError::NotExpectedTag("enumeratedValue".to_string()).at(t.id()))
                        }
                    })
                    .collect();
                values?
            },
        })
    }
}

struct DimIndex;

impl Parse for DimIndex {
    type Object = Vec<String>;
    type Error = SVDErrorAt;
    type Config = Config;

    fn parse(tree: &Node, _config: &Self::Config) -> Result<Vec<String>, Self::Error> {
        DimElement::parse_indexes(tree.get_text()?)
            .ok_or_else(|| SVDError::DimIndexParse.at(tree.id()))
    }
}