Skip to main content

xidl_parser/hir/
compound.rs

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 annotations: Vec<Annotation>,
98    pub ident: String,
99}
100
101impl UnionDef {
102    pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
103        config.resolve_for_annotations(&self.annotations)
104    }
105}
106
107impl BitsetDcl {
108    pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
109        config.resolve_for_annotations(&self.annotations)
110    }
111}
112
113impl BitmaskDcl {
114    pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
115        config.resolve_for_annotations(&self.annotations)
116    }
117}
118
119impl From<crate::typed_ast::ConstrTypeDcl> for ConstrTypeDcl {
120    fn from(value: crate::typed_ast::ConstrTypeDcl) -> Self {
121        match value {
122            crate::typed_ast::ConstrTypeDcl::StructDcl(value) => value.into(),
123            crate::typed_ast::ConstrTypeDcl::UnionDcl(value) => value.into(),
124            crate::typed_ast::ConstrTypeDcl::EnumDcl(value) => Self::EnumDcl(value.into()),
125            crate::typed_ast::ConstrTypeDcl::BitsetDcl(value) => Self::BitsetDcl(value.into()),
126            crate::typed_ast::ConstrTypeDcl::BitmaskDcl(value) => Self::BitmaskDcl(value.into()),
127        }
128    }
129}
130
131impl From<crate::typed_ast::StructDcl> for ConstrTypeDcl {
132    fn from(value: crate::typed_ast::StructDcl) -> Self {
133        match value {
134            crate::typed_ast::StructDcl::StructForwardDcl(value) => {
135                Self::StructForwardDcl(value.into())
136            }
137            crate::typed_ast::StructDcl::StructDef(value) => Self::StructDcl(value.into()),
138        }
139    }
140}
141
142impl From<crate::typed_ast::UnionDcl> for ConstrTypeDcl {
143    fn from(value: crate::typed_ast::UnionDcl) -> Self {
144        match value {
145            crate::typed_ast::UnionDcl::UnionForwardDcl(value) => {
146                Self::UnionForwardDcl(value.into())
147            }
148            crate::typed_ast::UnionDcl::UnionDef(value) => Self::UnionDef(value.into()),
149        }
150    }
151}
152
153impl From<crate::typed_ast::UnionForwardDcl> for UnionForwardDcl {
154    fn from(value: crate::typed_ast::UnionForwardDcl) -> Self {
155        Self {
156            annotations: vec![],
157            ident: value.0.0,
158        }
159    }
160}
161
162impl From<crate::typed_ast::UnionDef> for UnionDef {
163    fn from(value: crate::typed_ast::UnionDef) -> Self {
164        let mut cases = value
165            .case
166            .into_iter()
167            .map(Case::from)
168            .collect::<Vec<Case>>();
169        let mut member_ids = std::collections::HashMap::new();
170        let mut next_field_id = 1u32;
171
172        for case in &mut cases {
173            let name = declarator_name(&case.element.value).to_string();
174            if let Some(id) = case.element.field_id {
175                let entry = member_ids.entry(name.clone()).or_insert(id);
176                case.element.field_id = Some(*entry);
177            } else if let Some(existing) = member_ids.get(&name) {
178                case.element.field_id = Some(*existing);
179            } else {
180                member_ids.insert(name, next_field_id);
181                case.element.field_id = Some(next_field_id);
182                next_field_id += 1;
183            }
184        }
185
186        Self {
187            annotations: vec![],
188            ident: value.ident.0,
189            switch_type_spec: value.switch_type_spec.into(),
190            case: cases,
191        }
192    }
193}
194
195impl From<crate::typed_ast::Case> for Case {
196    fn from(value: crate::typed_ast::Case) -> Self {
197        Self {
198            label: value.label.into_iter().map(Into::into).collect(),
199            element: value.element.into(),
200        }
201    }
202}
203
204impl From<crate::typed_ast::CaseLabel> for CaseLabel {
205    fn from(value: crate::typed_ast::CaseLabel) -> Self {
206        match value {
207            crate::typed_ast::CaseLabel::Case(value) => Self::Value(value.into()),
208            crate::typed_ast::CaseLabel::Default => Self::Default,
209        }
210    }
211}
212
213impl From<crate::typed_ast::ElementSpec> for ElementSpec {
214    fn from(value: crate::typed_ast::ElementSpec) -> Self {
215        let annotations = expand_annotations(value.annotations);
216        Self {
217            field_id: annotation_id_value(&annotations),
218            annotations,
219            ty: value.ty.into(),
220            value: value.value.into(),
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        Self {
292            annotations: vec![],
293            ident: value.ident.0,
294            value: value.value.into_iter().map(Into::into).collect(),
295        }
296    }
297}
298
299impl From<crate::typed_ast::BitValue> for BitValue {
300    fn from(value: crate::typed_ast::BitValue) -> Self {
301        Self {
302            annotations: expand_annotations(value.annotations),
303            ident: value.ident.0,
304        }
305    }
306}
307
308fn declarator_name(value: &Declarator) -> &str {
309    match value {
310        Declarator::SimpleDeclarator(value) => &value.0,
311        Declarator::ArrayDeclarator(value) => &value.ident,
312    }
313}