1use super::*;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub enum ConstrTypeDcl {
6 StructForwardDcl(StructForwardDcl),
7 StructDcl(StructDcl),
8 EnumDcl(EnumDcl),
9 UnionForwardDcl(UnionForwardDcl),
10 UnionDef(UnionDef),
11 BitsetDcl(BitsetDcl),
12 BitmaskDcl(BitmaskDcl),
13}
14
15impl ConstrTypeDcl {
16 pub(crate) fn ident(&self) -> &str {
18 match self {
19 Self::StructDcl(value) => &value.ident,
20 Self::StructForwardDcl(value) => &value.ident,
21 Self::UnionDef(value) => &value.ident,
22 Self::UnionForwardDcl(value) => &value.ident,
23 Self::EnumDcl(value) => &value.ident,
24 Self::BitsetDcl(value) => &value.ident,
25 Self::BitmaskDcl(value) => &value.ident,
26 }
27 }
28}
29
30#[derive(Debug, Serialize, Deserialize, Clone)]
31pub struct UnionForwardDcl {
32 pub annotations: Vec<Annotation>,
33 pub ident: String,
34}
35
36#[derive(Debug, Serialize, Deserialize, Clone)]
37pub struct UnionDef {
38 pub annotations: Vec<Annotation>,
39 pub ident: String,
40 pub switch_type_spec: SwitchTypeSpec,
41 pub case: Vec<Case>,
42}
43
44#[derive(Debug, Serialize, Deserialize, Clone)]
45pub struct Case {
46 pub label: Vec<CaseLabel>,
47 pub element: ElementSpec,
48}
49
50#[derive(Debug, Serialize, Deserialize, Clone)]
51pub enum CaseLabel {
52 Value(ConstExpr),
53 Default,
54}
55
56#[derive(Debug, Serialize, Deserialize, Clone)]
57pub struct ElementSpec {
58 pub annotations: Vec<Annotation>,
59 pub ty: ElementSpecTy,
60 pub value: Declarator,
61 pub field_id: Option<u32>,
62 pub recursive: bool,
63}
64
65#[derive(Debug, Serialize, Deserialize, Clone)]
66pub enum ElementSpecTy {
67 TypeSpec(TypeSpec),
68 ConstrTypeDcl(ConstrTypeDcl),
69}
70
71#[derive(Debug, Serialize, Deserialize, Clone)]
72pub enum SwitchTypeSpec {
73 IntegerType(IntegerType),
74 CharType,
75 WideCharType,
76 BooleanType,
77 ScopedName(ScopedName),
78 OctetType,
79}
80
81#[derive(Debug, Serialize, Deserialize, Clone)]
82pub struct BitsetDcl {
83 pub annotations: Vec<Annotation>,
84 pub ident: String,
85 pub parent: Option<ScopedName>,
86 pub field: Vec<BitField>,
87}
88
89#[derive(Clone, Debug, Serialize, Deserialize)]
90pub enum BitFieldType {
91 Bool,
92 Octec,
93 SignedInt,
94 UnsignedInt,
95}
96
97#[derive(Debug, Serialize, Deserialize, Clone)]
98pub struct BitField {
99 pub ident: String,
100 pub pos: PositiveIntConst,
101 pub ty: Option<BitFieldType>,
102}
103
104#[derive(Debug, Serialize, Deserialize, Clone)]
105pub struct BitmaskDcl {
106 pub annotations: Vec<Annotation>,
107 pub ident: String,
108 pub value: Vec<BitValue>,
109}
110
111#[derive(Debug, Serialize, Deserialize, Clone)]
112pub struct BitValue {
113 pub position: usize,
114 pub annotations: Vec<Annotation>,
115 pub ident: String,
116}
117
118impl From<crate::typed_ast::ConstrTypeDcl> for ConstrTypeDcl {
119 fn from(value: crate::typed_ast::ConstrTypeDcl) -> Self {
120 match value {
121 crate::typed_ast::ConstrTypeDcl::StructDcl(value) => value.into(),
122 crate::typed_ast::ConstrTypeDcl::UnionDcl(value) => value.into(),
123 crate::typed_ast::ConstrTypeDcl::EnumDcl(value) => Self::EnumDcl(value.into()),
124 crate::typed_ast::ConstrTypeDcl::BitsetDcl(value) => Self::BitsetDcl(value.into()),
125 crate::typed_ast::ConstrTypeDcl::BitmaskDcl(value) => Self::BitmaskDcl(value.into()),
126 }
127 }
128}
129
130impl From<crate::typed_ast::StructDcl> for ConstrTypeDcl {
131 fn from(value: crate::typed_ast::StructDcl) -> Self {
132 match value {
133 crate::typed_ast::StructDcl::StructForwardDcl(value) => {
134 Self::StructForwardDcl(value.into())
135 }
136 crate::typed_ast::StructDcl::StructDef(value) => Self::StructDcl(value.into()),
137 }
138 }
139}
140
141impl From<crate::typed_ast::UnionDcl> for ConstrTypeDcl {
142 fn from(value: crate::typed_ast::UnionDcl) -> Self {
143 match value {
144 crate::typed_ast::UnionDcl::UnionForwardDcl(value) => {
145 Self::UnionForwardDcl(value.into())
146 }
147 crate::typed_ast::UnionDcl::UnionDef(value) => Self::UnionDef(value.into()),
148 }
149 }
150}
151
152impl From<crate::typed_ast::UnionForwardDcl> for UnionForwardDcl {
153 fn from(value: crate::typed_ast::UnionForwardDcl) -> Self {
154 Self {
155 annotations: vec![],
156 ident: value.0.0,
157 }
158 }
159}
160
161impl From<crate::typed_ast::UnionDef> for UnionDef {
162 fn from(value: crate::typed_ast::UnionDef) -> Self {
163 let mut cases = value
164 .case
165 .into_iter()
166 .map(Case::from)
167 .collect::<Vec<Case>>();
168 let mut member_ids = std::collections::HashMap::new();
169 let mut next_field_id = 1u32;
170
171 for case in &mut cases {
172 let name = declarator_name(&case.element.value).to_string();
173 if let Some(id) = case.element.field_id {
174 let entry = member_ids.entry(name.clone()).or_insert(id);
175 case.element.field_id = Some(*entry);
176 } else if let Some(existing) = member_ids.get(&name) {
177 case.element.field_id = Some(*existing);
178 } else {
179 member_ids.insert(name, next_field_id);
180 case.element.field_id = Some(next_field_id);
181 next_field_id += 1;
182 }
183 }
184
185 Self {
186 annotations: vec![],
187 ident: value.ident.0,
188 switch_type_spec: value.switch_type_spec.into(),
189 case: cases,
190 }
191 }
192}
193
194impl From<crate::typed_ast::Case> for Case {
195 fn from(value: crate::typed_ast::Case) -> Self {
196 Self {
197 label: value.label.into_iter().map(Into::into).collect(),
198 element: value.element.into(),
199 }
200 }
201}
202
203impl From<crate::typed_ast::CaseLabel> for CaseLabel {
204 fn from(value: crate::typed_ast::CaseLabel) -> Self {
205 match value {
206 crate::typed_ast::CaseLabel::Case(value) => Self::Value(value.into()),
207 crate::typed_ast::CaseLabel::Default => Self::Default,
208 }
209 }
210}
211
212impl From<crate::typed_ast::ElementSpec> for ElementSpec {
213 fn from(value: crate::typed_ast::ElementSpec) -> Self {
214 let annotations = expand_annotations(value.annotations);
215 Self {
216 field_id: annotation_id_value(&annotations),
217 annotations,
218 ty: value.ty.into(),
219 value: value.value.into(),
220 recursive: false,
221 }
222 }
223}
224
225impl From<crate::typed_ast::ElementSpecTy> for ElementSpecTy {
226 fn from(value: crate::typed_ast::ElementSpecTy) -> Self {
227 match value {
228 crate::typed_ast::ElementSpecTy::TypeSpec(value) => Self::TypeSpec(value.into()),
229 crate::typed_ast::ElementSpecTy::ConstrTypeDcl(value) => {
230 Self::ConstrTypeDcl(value.into())
231 }
232 }
233 }
234}
235
236impl From<crate::typed_ast::SwitchTypeSpec> for SwitchTypeSpec {
237 fn from(value: crate::typed_ast::SwitchTypeSpec) -> Self {
238 match value {
239 crate::typed_ast::SwitchTypeSpec::IntegerType(value) => Self::IntegerType(value.into()),
240 crate::typed_ast::SwitchTypeSpec::CharType(_) => Self::CharType,
241 crate::typed_ast::SwitchTypeSpec::WideCharType(_) => Self::WideCharType,
242 crate::typed_ast::SwitchTypeSpec::BooleanType(_) => Self::BooleanType,
243 crate::typed_ast::SwitchTypeSpec::ScopedName(value) => Self::ScopedName(value.into()),
244 crate::typed_ast::SwitchTypeSpec::OctetType(_) => Self::OctetType,
245 }
246 }
247}
248
249impl From<crate::typed_ast::BitsetDcl> for BitsetDcl {
250 fn from(value: crate::typed_ast::BitsetDcl) -> Self {
251 let mut field = Vec::new();
252 for bitfield in value.field {
253 let pos = bitfield.spec.pos;
254 let ty = bitfield.spec.dst_ty.map(Into::into);
255 for ident in bitfield.ident {
256 field.push(BitField {
257 ident: ident.0,
258 pos: pos.clone().into(),
259 ty: ty.clone(),
260 });
261 }
262 }
263
264 Self {
265 annotations: vec![],
266 ident: value.ident.0,
267 parent: value.parent.map(Into::into),
268 field,
269 }
270 }
271}
272
273impl From<crate::typed_ast::DestinationType> for BitFieldType {
274 fn from(value: crate::typed_ast::DestinationType) -> Self {
275 match value {
276 crate::typed_ast::DestinationType::BooleanType(_) => Self::Bool,
277 crate::typed_ast::DestinationType::OctetType(_) => Self::Octec,
278 crate::typed_ast::DestinationType::IntegerType(value) => {
279 if matches!(value, crate::typed_ast::IntegerType::SignedInt(_)) {
280 Self::SignedInt
281 } else {
282 Self::UnsignedInt
283 }
284 }
285 }
286 }
287}
288
289impl From<crate::typed_ast::BitmaskDcl> for BitmaskDcl {
290 fn from(value: crate::typed_ast::BitmaskDcl) -> Self {
291 let mut bits = vec![];
292 for (idx, bitvalue) in value.value.into_iter().enumerate() {
293 let mut position = idx;
294 for annotation in &bitvalue.annotations {
295 let crate::typed_ast::AnnotationName::Builtin(name) = &annotation.name else {
296 continue;
297 };
298 if !name.eq_ignore_ascii_case("position") {
299 continue;
300 }
301
302 let Some(crate::typed_ast::AnnotationParams::Raw(v)) = &annotation.params else {
303 continue;
304 };
305
306 if let Ok(v) = v.parse::<usize>() {
307 position = v;
308 }
309 }
310 let mut bit: BitValue = bitvalue.into();
311 bit.position = position;
312 bits.push(bit);
313 }
314 Self {
315 annotations: vec![],
316 ident: value.ident.0,
317 value: bits,
318 }
319 }
320}
321
322impl From<crate::typed_ast::BitValue> for BitValue {
323 fn from(value: crate::typed_ast::BitValue) -> Self {
324 Self {
325 position: 0,
326 annotations: expand_annotations(value.annotations),
327 ident: value.ident.0,
328 }
329 }
330}
331
332fn declarator_name(value: &Declarator) -> &str {
333 match value {
334 Declarator::SimpleDeclarator(value) => &value.0,
335 Declarator::ArrayDeclarator(value) => &value.ident,
336 }
337}