1use bincode::Decode;
2use bincode::Encode;
3use schemars::JsonSchema;
4use serde::Deserialize;
5use serde::Serialize;
6
7use crate::tree::comment::CommentGroup;
8use crate::tree::definition::attribute::AttributeGroupDefinition;
9use crate::tree::definition::constant::ClassishConstantDefinition;
10use crate::tree::definition::function::MethodDefinition;
11use crate::tree::expression::Expression;
12use crate::tree::identifier::Identifier;
13use crate::tree::identifier::TemplatedIdentifier;
14use crate::tree::token::Keyword;
15use crate::tree::utils::CommaSeparated;
16use crate::tree::Node;
17
18#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
19#[serde(rename_all = "snake_case", tag = "type", content = "data")]
20pub enum EnumDefinition {
21 Backed(BackedEnumDefinition),
22 Unit(UnitEnumDefinition),
23}
24
25#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
26#[serde(rename_all = "snake_case")]
27pub struct UnitEnumDefinition {
28 pub comments: CommentGroup,
29 pub attributes: Vec<AttributeGroupDefinition>,
30 pub r#enum: Keyword,
31 pub name: Identifier,
32 pub implements: Option<EnumImplementsDefinition>,
33 pub body: UnitEnumBodyDefinition,
34}
35
36#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
37#[serde(rename_all = "snake_case")]
38pub struct EnumImplementsDefinition {
39 pub implements: Keyword,
40 pub interfaces: CommaSeparated<TemplatedIdentifier>,
41}
42
43#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
44#[serde(rename_all = "snake_case")]
45pub struct UnitEnumBodyDefinition {
46 pub left_brace: usize,
47 pub members: Vec<UnitEnumMemberDefinition>,
48 pub right_brace: usize,
49}
50
51#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
52#[serde(rename_all = "snake_case", tag = "type", content = "value")]
53pub enum UnitEnumMemberDefinition {
54 Case(UnitEnumCaseDefinition),
55 Method(MethodDefinition),
56 Constant(ClassishConstantDefinition),
57}
58
59#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
60#[serde(rename_all = "snake_case")]
61pub struct UnitEnumCaseDefinition {
62 pub attributes: Vec<AttributeGroupDefinition>,
63 pub case: Keyword,
64 pub name: Identifier,
65 pub semicolon: usize,
66}
67
68#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
69#[serde(rename_all = "snake_case")]
70pub struct BackedEnumDefinition {
71 pub comments: CommentGroup,
72 pub attributes: Vec<AttributeGroupDefinition>,
73 pub r#enum: Keyword,
74 pub name: Identifier,
75 pub backed_type: BackedEnumTypeDefinition,
76 pub implements: Option<EnumImplementsDefinition>,
77 pub body: BackedEnumBodyDefinition,
78}
79
80#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize, Serialize, Encode, Decode, JsonSchema)]
81#[serde(tag = "type", content = "value")]
82pub enum BackedEnumTypeDefinition {
83 String(usize, Identifier),
84 Int(usize, Identifier),
85}
86
87#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
88#[serde(rename_all = "snake_case")]
89pub struct BackedEnumBodyDefinition {
90 pub left_brace: usize,
91 pub members: Vec<BackedEnumMemberDefinition>,
92 pub right_brace: usize,
93}
94
95#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
96#[serde(rename_all = "snake_case", tag = "type", content = "value")]
97pub enum BackedEnumMemberDefinition {
98 Case(BackedEnumCaseDefinition),
99 Method(MethodDefinition),
100 Constant(ClassishConstantDefinition),
101}
102
103#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
104#[serde(rename_all = "snake_case")]
105pub struct BackedEnumCaseDefinition {
106 pub attributes: Vec<AttributeGroupDefinition>,
107 pub case: Keyword,
108 pub name: Identifier,
109 pub equals: usize,
110 pub value: Expression,
111 pub semicolon: usize,
112}
113
114impl Node for EnumDefinition {
115 fn comments(&self) -> Option<&CommentGroup> {
116 None
117 }
118
119 fn initial_position(&self) -> usize {
120 match &self {
121 Self::Backed(definition) => definition.initial_position(),
122 Self::Unit(definition) => definition.initial_position(),
123 }
124 }
125
126 fn final_position(&self) -> usize {
127 match &self {
128 Self::Backed(definition) => definition.final_position(),
129 Self::Unit(definition) => definition.final_position(),
130 }
131 }
132
133 fn children(&self) -> Vec<&dyn Node> {
134 match &self {
135 Self::Backed(definition) => vec![definition],
136 Self::Unit(definition) => vec![definition],
137 }
138 }
139
140 fn get_description(&self) -> String {
141 match &self {
142 Self::Backed(definition) => definition.get_description(),
143 Self::Unit(definition) => definition.get_description(),
144 }
145 }
146}
147
148impl Node for UnitEnumDefinition {
149 fn comments(&self) -> Option<&CommentGroup> {
150 Some(&self.comments)
151 }
152
153 fn initial_position(&self) -> usize {
154 if let Some(attributes) = self.attributes.first() {
155 attributes.initial_position()
156 } else {
157 self.r#enum.initial_position()
158 }
159 }
160
161 fn final_position(&self) -> usize {
162 self.body.right_brace + 1
163 }
164
165 fn children(&self) -> Vec<&dyn Node> {
166 let mut children: Vec<&dyn Node> = vec![&self.r#enum, &self.name];
167
168 for attribute in &self.attributes {
169 children.push(attribute);
170 }
171
172 if let Some(implements) = &self.implements {
173 children.push(implements);
174 }
175
176 children.push(&self.body);
177
178 children
179 }
180
181 fn get_description(&self) -> String {
182 "unit enum definition".to_string()
183 }
184}
185
186impl Node for EnumImplementsDefinition {
187 fn initial_position(&self) -> usize {
188 self.implements.initial_position()
189 }
190
191 fn final_position(&self) -> usize {
192 if let Some(last_interface) = self.interfaces.inner.last() {
193 let last_interface_position = last_interface.final_position();
194 if let Some(last_comma) = self.interfaces.commas.last() {
195 let last_comma_position = last_comma + 1;
196 if last_comma_position > last_interface_position {
197 return last_comma_position;
198 }
199 }
200
201 return last_interface_position;
202 }
203
204 self.implements.final_position()
205 }
206
207 fn children(&self) -> Vec<&dyn Node> {
208 let mut children: Vec<&dyn Node> = vec![&self.implements];
209
210 for interface in &self.interfaces.inner {
211 children.push(interface);
212 }
213
214 children
215 }
216
217 fn get_description(&self) -> String {
218 "enum implements definition".to_string()
219 }
220}
221
222impl Node for UnitEnumBodyDefinition {
223 fn initial_position(&self) -> usize {
224 self.left_brace
225 }
226
227 fn final_position(&self) -> usize {
228 self.right_brace + 1
229 }
230
231 fn children(&self) -> Vec<&dyn Node> {
232 self.members
233 .iter()
234 .map(|member| member as &dyn Node)
235 .collect()
236 }
237
238 fn get_description(&self) -> String {
239 "unit enum body definition".to_string()
240 }
241}
242
243impl Node for UnitEnumMemberDefinition {
244 fn initial_position(&self) -> usize {
245 match &self {
246 Self::Case(case) => case.initial_position(),
247 Self::Method(method) => method.initial_position(),
248 Self::Constant(constant) => constant.initial_position(),
249 }
250 }
251
252 fn final_position(&self) -> usize {
253 match &self {
254 Self::Case(case) => case.final_position(),
255 Self::Method(method) => method.final_position(),
256 Self::Constant(constant) => constant.final_position(),
257 }
258 }
259
260 fn children(&self) -> Vec<&dyn Node> {
261 match &self {
262 Self::Case(case) => vec![case],
263 Self::Method(method) => vec![method],
264 Self::Constant(constant) => vec![constant],
265 }
266 }
267
268 fn get_description(&self) -> String {
269 match &self {
270 Self::Case(case) => case.get_description(),
271 Self::Method(method) => method.get_description(),
272 Self::Constant(constant) => constant.get_description(),
273 }
274 }
275}
276
277impl Node for UnitEnumCaseDefinition {
278 fn initial_position(&self) -> usize {
279 if let Some(attributes) = self.attributes.first() {
280 attributes.initial_position()
281 } else {
282 self.case.initial_position()
283 }
284 }
285
286 fn final_position(&self) -> usize {
287 self.semicolon + 1
288 }
289
290 fn children(&self) -> Vec<&dyn Node> {
291 let mut children: Vec<&dyn Node> = vec![&self.case];
292 for attribute in &self.attributes {
293 children.push(attribute);
294 }
295
296 children
297 }
298
299 fn get_description(&self) -> String {
300 "unit enum case definition".to_string()
301 }
302}
303
304impl Node for BackedEnumDefinition {
305 fn comments(&self) -> Option<&CommentGroup> {
306 Some(&self.comments)
307 }
308
309 fn initial_position(&self) -> usize {
310 if let Some(attributes) = self.attributes.first() {
311 attributes.initial_position()
312 } else {
313 self.r#enum.initial_position()
314 }
315 }
316
317 fn final_position(&self) -> usize {
318 self.body.right_brace + 1
319 }
320
321 fn children(&self) -> Vec<&dyn Node> {
322 let mut children: Vec<&dyn Node> = vec![&self.r#enum, &self.name, &self.backed_type];
323 for attribute in &self.attributes {
324 children.push(attribute);
325 }
326
327 if let Some(implements) = &self.implements {
328 children.push(implements);
329 }
330
331 children.push(&self.body);
332
333 children
334 }
335
336 fn get_description(&self) -> String {
337 "backed enum definition".to_string()
338 }
339}
340
341impl Node for BackedEnumTypeDefinition {
342 fn initial_position(&self) -> usize {
343 match &self {
344 Self::String(colon, _) | Self::Int(colon, _) => *colon,
345 }
346 }
347
348 fn final_position(&self) -> usize {
349 match &self {
350 Self::String(_, identifier) | Self::Int(_, identifier) => identifier.final_position(),
351 }
352 }
353
354 fn children(&self) -> Vec<&dyn Node> {
355 match &self {
356 Self::String(_, identifier) | Self::Int(_, identifier) => vec![identifier],
357 }
358 }
359
360 fn get_description(&self) -> String {
361 "backed enum type definition".to_string()
362 }
363}
364
365impl Node for BackedEnumBodyDefinition {
366 fn initial_position(&self) -> usize {
367 self.left_brace
368 }
369
370 fn final_position(&self) -> usize {
371 self.right_brace + 1
372 }
373
374 fn children(&self) -> Vec<&dyn Node> {
375 self.members
376 .iter()
377 .map(|member| member as &dyn Node)
378 .collect()
379 }
380
381 fn get_description(&self) -> String {
382 "backed enum body definition".to_string()
383 }
384}
385
386impl Node for BackedEnumMemberDefinition {
387 fn initial_position(&self) -> usize {
388 match &self {
389 Self::Case(case) => case.initial_position(),
390 Self::Method(method) => method.initial_position(),
391 Self::Constant(constant) => constant.initial_position(),
392 }
393 }
394
395 fn final_position(&self) -> usize {
396 match &self {
397 Self::Case(case) => case.final_position(),
398 Self::Method(method) => method.final_position(),
399 Self::Constant(constant) => constant.final_position(),
400 }
401 }
402
403 fn children(&self) -> Vec<&dyn Node> {
404 match &self {
405 Self::Case(case) => vec![case],
406 Self::Method(method) => vec![method],
407 Self::Constant(constant) => vec![constant],
408 }
409 }
410
411 fn get_description(&self) -> String {
412 match &self {
413 Self::Case(case) => case.get_description(),
414 Self::Method(method) => method.get_description(),
415 Self::Constant(constant) => constant.get_description(),
416 }
417 }
418}
419
420impl Node for BackedEnumCaseDefinition {
421 fn initial_position(&self) -> usize {
422 if let Some(attributes) = self.attributes.first() {
423 attributes.initial_position()
424 } else {
425 self.case.initial_position()
426 }
427 }
428
429 fn final_position(&self) -> usize {
430 self.semicolon + 1
431 }
432
433 fn children(&self) -> Vec<&dyn Node> {
434 vec![&self.case, &self.name, &self.value]
435 }
436
437 fn get_description(&self) -> String {
438 "backed enum case definition".to_string()
439 }
440}