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