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