1#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
3pub enum Error {
4 #[error("bitRange width of 0 does not make sense")]
6 ZeroWidth,
7}
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct BitRange {
12 pub offset: u32,
14
15 pub width: u32,
17
18 pub range_type: BitRangeType,
20}
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum BitRangeType {
25 BitRange,
27 OffsetWidth,
29 MsbLsb,
31}
32
33impl BitRange {
34 pub fn lsb(&self) -> u32 {
36 self.offset
37 }
38 pub fn msb(&self) -> u32 {
40 self.offset + self.width - 1
41 }
42 pub fn bit_range(&self) -> String {
44 format!("[{}:{}]", self.msb(), self.lsb())
45 }
46 pub fn from_offset_width(offset: u32, width: u32) -> Self {
48 Self {
49 offset,
50 width,
51 range_type: BitRangeType::OffsetWidth,
52 }
53 }
54
55 pub fn from_msb_lsb(msb: u32, lsb: u32) -> Self {
57 Self {
58 offset: lsb,
59 width: msb - lsb + 1,
60 range_type: BitRangeType::MsbLsb,
61 }
62 }
63 pub fn from_bit_range(text: &str) -> Option<Self> {
65 if !text.starts_with('[') || !text.ends_with(']') {
66 return None;
67 }
68 let mut parts = text[1..text.len() - 1].split(':');
69 let msb = parts.next()?.parse::<u32>().ok()?;
70 let lsb = parts.next()?.parse::<u32>().ok()?;
71 Some(Self {
72 offset: lsb,
73 width: msb - lsb + 1,
74 range_type: BitRangeType::BitRange,
75 })
76 }
77}
78
79#[cfg(feature = "serde")]
80mod ser_de {
81 use super::*;
82 use serde::{Deserialize, Deserializer, Serialize, Serializer};
83
84 #[derive(serde::Serialize, serde::Deserialize)]
85 #[serde(untagged)]
86 enum SerBitRange {
87 #[serde(rename_all = "camelCase")]
88 BitRange {
89 bit_range: String,
90 },
91 #[serde(rename_all = "camelCase")]
92 OffsetWidth {
93 bit_offset: u32,
94 bit_width: u32,
95 },
96 MsbLsb {
97 lsb: u32,
98 msb: u32,
99 },
100 }
101
102 impl From<BitRange> for SerBitRange {
103 fn from(br: BitRange) -> Self {
104 match br.range_type {
105 BitRangeType::BitRange => SerBitRange::BitRange {
106 bit_range: br.bit_range(),
107 },
108 BitRangeType::OffsetWidth => SerBitRange::OffsetWidth {
109 bit_offset: br.offset,
110 bit_width: br.width,
111 },
112 BitRangeType::MsbLsb => SerBitRange::MsbLsb {
113 msb: br.msb(),
114 lsb: br.lsb(),
115 },
116 }
117 }
118 }
119
120 impl Serialize for BitRange {
121 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
122 where
123 S: Serializer,
124 {
125 let bit_range = SerBitRange::from(*self);
126 bit_range.serialize(serializer)
127 }
128 }
129
130 impl<'de> Deserialize<'de> for BitRange {
131 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
132 where
133 D: Deserializer<'de>,
134 {
135 match SerBitRange::deserialize(deserializer)? {
136 SerBitRange::BitRange { bit_range } => BitRange::from_bit_range(&bit_range)
137 .ok_or_else(|| serde::de::Error::custom("Can't parse bitRange")),
138 SerBitRange::OffsetWidth {
139 bit_offset,
140 bit_width,
141 } => Ok(BitRange::from_offset_width(bit_offset, bit_width)),
142 SerBitRange::MsbLsb { msb, lsb } => Ok(BitRange::from_msb_lsb(msb, lsb)),
143 }
144 }
145 }
146}