svd_parser/
bitrange.rs

1use super::*;
2use crate::svd::{BitRange, BitRangeType};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub enum InvalidBitRange {
6    Syntax,
7    ParseError,
8    MsbLsb,
9    Empty,
10    Size,
11}
12
13impl Parse for BitRange {
14    type Object = Self;
15    type Error = SVDErrorAt;
16    type Config = Config;
17
18    fn parse(tree: &Node, _config: &Self::Config) -> Result<Self, Self::Error> {
19        let (end, start, range_type): (u32, u32, BitRangeType) =
20            if let Some(range) = tree.get_child("bitRange") {
21                let text = range.text().ok_or_else(|| {
22                    SVDError::InvalidBitRange(InvalidBitRange::Empty).at(tree.id())
23                })?;
24                if !text.starts_with('[') {
25                    return Err(SVDError::InvalidBitRange(InvalidBitRange::Syntax).at(tree.id()));
26                    // TODO: Maybe have a MissingOpen/MissingClosing variant
27                }
28                if !text.ends_with(']') {
29                    return Err(SVDError::InvalidBitRange(InvalidBitRange::Syntax).at(tree.id()));
30                    // TODO: Maybe have a MissingOpen/MissingClosing variant
31                }
32
33                let mut parts = text[1..text.len() - 1].split(':');
34                (
35                    parts
36                        .next()
37                        .ok_or_else(|| {
38                            SVDError::InvalidBitRange(InvalidBitRange::Syntax).at(tree.id())
39                        })?
40                        .parse::<u32>()
41                        .map_err(|_| {
42                            SVDError::InvalidBitRange(InvalidBitRange::ParseError).at(tree.id())
43                        })?,
44                    parts
45                        .next()
46                        .ok_or_else(|| {
47                            SVDError::InvalidBitRange(InvalidBitRange::Syntax).at(tree.id())
48                        })?
49                        .parse::<u32>()
50                        .map_err(|_| {
51                            SVDError::InvalidBitRange(InvalidBitRange::ParseError).at(tree.id())
52                        })?,
53                    BitRangeType::BitRange,
54                )
55            // TODO: Consider matching instead so we can say which of these tags are missing
56            } else if let (Some(lsb), Some(msb)) = (tree.get_child("lsb"), tree.get_child("msb")) {
57                (
58                    // TODO: `u32::parse` should not hide it's errors
59                    u32::parse(&msb, &()).map_err(|_| {
60                        SVDError::InvalidBitRange(InvalidBitRange::MsbLsb).at(tree.id())
61                    })?,
62                    u32::parse(&lsb, &()).map_err(|_| {
63                        SVDError::InvalidBitRange(InvalidBitRange::MsbLsb).at(tree.id())
64                    })?,
65                    BitRangeType::MsbLsb,
66                )
67            } else if let (Some(offset), Some(width)) =
68                (tree.get_child("bitOffset"), tree.get_child("bitWidth"))
69            {
70                // Special case because offset and width are directly provided
71                // (ie. do not need to be calculated as in the final step)
72                return Ok(BitRange {
73                    // TODO: capture that error comes from offset/width tag
74                    // TODO: `u32::parse` should not hide it's errors
75                    offset: u32::parse(&offset, &()).map_err(|_| {
76                        SVDError::InvalidBitRange(InvalidBitRange::ParseError).at(tree.id())
77                    })?,
78                    width: u32::parse(&width, &()).map_err(|_| {
79                        SVDError::InvalidBitRange(InvalidBitRange::ParseError).at(tree.id())
80                    })?,
81                    range_type: BitRangeType::OffsetWidth,
82                });
83            } else {
84                return Err(SVDError::InvalidBitRange(InvalidBitRange::Syntax).at(tree.id()));
85            };
86
87        if start > end {
88            return Err(SVDError::InvalidBitRange(InvalidBitRange::Size).at(tree.id()));
89        }
90        Ok(Self {
91            offset: start,
92            width: end - start + 1,
93            range_type,
94        })
95    }
96}