Skip to main content

xidl_parser/typed_ast/
union.rs

1use super::*;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Parser, Serialize, Deserialize)]
5pub struct EnumDcl {
6    pub ident: Identifier,
7    pub member: Vec<Enumerator>,
8}
9
10#[derive(Debug, Serialize, Deserialize)]
11pub struct Enumerator {
12    pub annotations: Vec<AnnotationAppl>,
13    pub ident: Identifier,
14}
15
16impl<'a> crate::parser::FromTreeSitter<'a> for Enumerator {
17    fn from_node(
18        node: tree_sitter::Node<'a>,
19        ctx: &mut crate::parser::ParseContext<'a>,
20    ) -> crate::error::ParserResult<Self> {
21        assert_eq!(node.kind_id(), xidl_parser_derive::node_id!("enumerator"));
22        let mut annotations = Vec::new();
23        let mut ident = None;
24        for ch in node.children(&mut node.walk()) {
25            match ch.kind_id() {
26                xidl_parser_derive::node_id!("annotation_appl")
27                | xidl_parser_derive::node_id!("extend_annotation_appl") => {
28                    annotations.push(AnnotationAppl::from_node(ch, ctx)?);
29                }
30                xidl_parser_derive::node_id!("identifier") => {
31                    ident = Some(Identifier::from_node(ch, ctx)?);
32                }
33                _ => {}
34            }
35        }
36        Ok(Self {
37            annotations,
38            ident: ident.ok_or_else(|| {
39                crate::error::ParseError::UnexpectedNode(format!(
40                    "parent: {}, got: missing identifier",
41                    node.kind()
42                ))
43            })?,
44        })
45    }
46}
47
48#[derive(Debug, Parser, Serialize, Deserialize)]
49pub enum UnionDcl {
50    UnionDef(UnionDef),
51    UnionForwardDcl(UnionForwardDcl),
52}
53
54#[derive(Debug, Parser, Serialize, Deserialize)]
55pub struct UnionDef {
56    pub ident: Identifier,
57    pub switch_type_spec: SwitchTypeSpec,
58    pub case: Vec<Case>,
59}
60#[derive(Debug, Parser, Serialize, Deserialize)]
61pub struct UnionForwardDcl(pub Identifier);
62
63#[derive(Debug, Parser, Serialize, Deserialize)]
64pub struct Case {
65    pub label: Vec<CaseLabel>,
66    pub element: ElementSpec,
67}
68
69#[derive(Debug, Serialize, Deserialize)]
70pub enum CaseLabel {
71    Case(ConstExpr),
72    Default,
73}
74
75impl<'a> crate::parser::FromTreeSitter<'a> for CaseLabel {
76    fn from_node(
77        node: tree_sitter::Node<'a>,
78        ctx: &mut crate::parser::ParseContext<'a>,
79    ) -> crate::error::ParserResult<Self> {
80        assert_eq!(node.kind_id(), xidl_parser_derive::node_id!("case_label"));
81        for ch in node.children(&mut node.walk()) {
82            if ch.kind_id() == xidl_parser_derive::node_id!("const_expr") {
83                return Ok(Self::Case(ConstExpr::from_node(ch, ctx)?));
84            }
85        }
86
87        let text = ctx.node_text(&node)?.trim();
88        if text.starts_with("default") {
89            return Ok(Self::Default);
90        }
91
92        Err(crate::error::ParseError::UnexpectedNode(format!(
93            "parent: {}, got: missing case label",
94            node.kind()
95        )))
96    }
97}
98
99#[derive(Debug, Serialize, Deserialize)]
100pub struct ElementSpec {
101    pub annotations: Vec<AnnotationAppl>,
102    pub ty: ElementSpecTy,
103    pub value: Declarator,
104}
105
106impl<'a> crate::parser::FromTreeSitter<'a> for ElementSpec {
107    fn from_node(
108        node: tree_sitter::Node<'a>,
109        ctx: &mut crate::parser::ParseContext<'a>,
110    ) -> crate::error::ParserResult<Self> {
111        assert_eq!(node.kind_id(), xidl_parser_derive::node_id!("element_spec"));
112        let mut annotations = vec![];
113        let mut ty = None;
114        let mut value = None;
115        for ch in node.children(&mut node.walk()) {
116            match ch.kind_id() {
117                xidl_parser_derive::node_id!("annotation_appl")
118                | xidl_parser_derive::node_id!("extend_annotation_appl") => {
119                    annotations.push(AnnotationAppl::from_node(ch, ctx)?);
120                }
121                xidl_parser_derive::node_id!("type_spec")
122                | xidl_parser_derive::node_id!("constr_type_dcl") => {
123                    ty = Some(crate::parser::FromTreeSitter::from_node(ch, ctx)?);
124                }
125                xidl_parser_derive::node_id!("declarator") => {
126                    value = Some(crate::parser::FromTreeSitter::from_node(ch, ctx)?);
127                }
128                _ => {}
129            }
130        }
131        Ok(Self {
132            annotations,
133            ty: ty.unwrap(),
134            value: value.unwrap(),
135        })
136    }
137}
138
139#[derive(Debug, Parser, Serialize, Deserialize)]
140#[ts(transparent)]
141pub enum ElementSpecTy {
142    TypeSpec(TypeSpec),
143    ConstrTypeDcl(ConstrTypeDcl),
144}
145
146#[derive(Debug, Parser, Serialize, Deserialize)]
147pub enum SwitchTypeSpec {
148    IntegerType(IntegerType),
149    CharType(CharType),
150    WideCharType(WideCharType),
151    BooleanType(BooleanType),
152    ScopedName(ScopedName),
153    OctetType(OctetType),
154}