xidl_parser/typed_ast/
union.rs1use 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}