1use super::{Comment, DocString, Ident, LitInt, LitUuid, Prelude, TypeNameOrInline};
2use crate::error::{
3 DuplicateEventId, DuplicateFunctionId, DuplicateServiceItem, InvalidEventId, InvalidFunctionId,
4 InvalidServiceVersion,
5};
6use crate::grammar::Rule;
7use crate::validate::Validate;
8use crate::warning::{BrokenDocLink, NonCamelCaseService, NonSnakeCaseEvent, NonSnakeCaseFunction};
9use crate::Span;
10use pest::iterators::Pair;
11
12#[derive(Debug, Clone)]
13pub struct ServiceDef {
14 span: Span,
15 comment: Vec<Comment>,
16 doc: Vec<DocString>,
17 name: Ident,
18 uuid_comment: Vec<Comment>,
19 uuid: LitUuid,
20 ver_comment: Vec<Comment>,
21 ver: LitInt,
22 items: Vec<ServiceItem>,
23 fn_fallback: Option<FunctionFallback>,
24 ev_fallback: Option<EventFallback>,
25}
26
27impl ServiceDef {
28 pub(crate) fn parse(pair: Pair<Rule>) -> Self {
29 assert_eq!(pair.as_rule(), Rule::service_def);
30
31 let span = Span::from_pair(&pair);
32 let mut pairs = pair.into_inner();
33 let mut prelude = Prelude::regular(&mut pairs);
34
35 pairs.next().unwrap(); let pair = pairs.next().unwrap();
38 let name = Ident::parse(pair);
39
40 pairs.next().unwrap(); let pair = pairs.next().unwrap();
43 let (uuid_comment, uuid) = Self::parse_uuid(pair);
44
45 let pair = pairs.next().unwrap();
46 let (ver_comment, ver) = Self::parse_version(pair);
47
48 let mut items = Vec::new();
49 let mut fn_fallback = None;
50 let mut ev_fallback = None;
51
52 for pair in pairs {
53 match pair.as_rule() {
54 Rule::service_item => items.push(ServiceItem::parse(pair)),
55
56 Rule::service_fallback => {
57 for pair in pair.into_inner() {
58 match pair.as_rule() {
59 Rule::fn_fallback => fn_fallback = Some(FunctionFallback::parse(pair)),
60 Rule::event_fallback => ev_fallback = Some(EventFallback::parse(pair)),
61 _ => unreachable!(),
62 }
63 }
64 }
65
66 Rule::tok_cur_close => break,
67 _ => unreachable!(),
68 }
69 }
70
71 Self {
72 span,
73 comment: prelude.take_comment(),
74 doc: prelude.take_doc(),
75 name,
76 uuid_comment,
77 uuid,
78 ver_comment,
79 ver,
80 items,
81 fn_fallback,
82 ev_fallback,
83 }
84 }
85
86 fn parse_uuid(pair: Pair<Rule>) -> (Vec<Comment>, LitUuid) {
87 assert_eq!(pair.as_rule(), Rule::service_uuid);
88
89 let mut pairs = pair.into_inner();
90 let mut prelude = Prelude::regular(&mut pairs);
91
92 pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
96 (prelude.take_comment(), LitUuid::parse(pair))
97 }
98
99 fn parse_version(pair: Pair<Rule>) -> (Vec<Comment>, LitInt) {
100 assert_eq!(pair.as_rule(), Rule::service_version);
101
102 let mut pairs = pair.into_inner();
103 let mut prelude = Prelude::regular(&mut pairs);
104
105 pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
109 (prelude.take_comment(), LitInt::parse(pair))
110 }
111
112 pub(crate) fn validate(&self, validate: &mut Validate) {
113 BrokenDocLink::validate(&self.doc, validate);
114 InvalidServiceVersion::validate(self, validate);
115 DuplicateServiceItem::validate(self, validate);
116 DuplicateFunctionId::validate(self, validate);
117 DuplicateEventId::validate(self, validate);
118 NonCamelCaseService::validate(self, validate);
119
120 self.name.validate(true, validate);
121
122 for item in &self.items {
123 item.validate(validate);
124 }
125
126 if let Some(ref fn_fallback) = self.fn_fallback {
127 fn_fallback.validate(validate);
128 }
129
130 if let Some(ref ev_fallback) = self.ev_fallback {
131 ev_fallback.validate(validate);
132 }
133 }
134
135 pub fn span(&self) -> Span {
136 self.span
137 }
138
139 pub fn comment(&self) -> &[Comment] {
140 &self.comment
141 }
142
143 pub fn doc(&self) -> &[DocString] {
144 &self.doc
145 }
146
147 pub fn name(&self) -> &Ident {
148 &self.name
149 }
150
151 pub fn uuid_comment(&self) -> &[Comment] {
152 &self.uuid_comment
153 }
154
155 pub fn uuid(&self) -> &LitUuid {
156 &self.uuid
157 }
158
159 pub fn version_comment(&self) -> &[Comment] {
160 &self.ver_comment
161 }
162
163 pub fn version(&self) -> &LitInt {
164 &self.ver
165 }
166
167 pub fn items(&self) -> &[ServiceItem] {
168 &self.items
169 }
170
171 pub fn function_fallback(&self) -> Option<&FunctionFallback> {
172 self.fn_fallback.as_ref()
173 }
174
175 pub fn event_fallback(&self) -> Option<&EventFallback> {
176 self.ev_fallback.as_ref()
177 }
178}
179
180#[derive(Debug, Clone)]
181#[allow(clippy::large_enum_variant)]
182pub enum ServiceItem {
183 Function(FunctionDef),
184 Event(EventDef),
185}
186
187impl ServiceItem {
188 fn parse(pair: Pair<Rule>) -> Self {
189 assert_eq!(pair.as_rule(), Rule::service_item);
190 let mut pairs = pair.into_inner();
191 let pair = pairs.next().unwrap();
192 match pair.as_rule() {
193 Rule::fn_def => Self::Function(FunctionDef::parse(pair)),
194 Rule::event_def => Self::Event(EventDef::parse(pair)),
195 _ => unreachable!(),
196 }
197 }
198
199 fn validate(&self, validate: &mut Validate) {
200 match self {
201 Self::Function(i) => i.validate(validate),
202 Self::Event(i) => i.validate(validate),
203 }
204 }
205
206 pub fn span(&self) -> Span {
207 match self {
208 Self::Function(i) => i.span(),
209 Self::Event(i) => i.span(),
210 }
211 }
212
213 pub fn doc(&self) -> &[DocString] {
214 match self {
215 Self::Function(i) => i.doc(),
216 Self::Event(i) => i.doc(),
217 }
218 }
219
220 pub fn name(&self) -> &Ident {
221 match self {
222 Self::Function(i) => i.name(),
223 Self::Event(i) => i.name(),
224 }
225 }
226}
227
228#[derive(Debug, Clone)]
229pub struct FunctionDef {
230 span: Span,
231 comment: Vec<Comment>,
232 doc: Vec<DocString>,
233 name: Ident,
234 id: LitInt,
235 args: Option<FunctionPart>,
236 ok: Option<FunctionPart>,
237 err: Option<FunctionPart>,
238}
239
240impl FunctionDef {
241 fn parse(pair: Pair<Rule>) -> Self {
242 assert_eq!(pair.as_rule(), Rule::fn_def);
243
244 let span = Span::from_pair(&pair);
245 let mut pairs = pair.into_inner();
246 let mut prelude = Prelude::regular(&mut pairs);
247
248 pairs.next().unwrap(); let pair = pairs.next().unwrap();
251 let name = Ident::parse(pair);
252
253 pairs.next().unwrap(); let pair = pairs.next().unwrap();
256 let id = LitInt::parse(pair);
257
258 let mut args = None;
259 let mut ok = None;
260 let mut err = None;
261 for pair in pairs {
262 match pair.as_rule() {
263 Rule::fn_args => args = Some(FunctionPart::parse(pair)),
264 Rule::fn_ok => ok = Some(FunctionPart::parse(pair)),
265 Rule::fn_err => err = Some(FunctionPart::parse(pair)),
266 Rule::type_name_or_inline => ok = Some(FunctionPart::parse(pair)),
267
268 Rule::tok_cur_open | Rule::tok_cur_close | Rule::tok_eq | Rule::tok_term => {}
269 _ => unreachable!(),
270 }
271 }
272
273 Self {
274 span,
275 comment: prelude.take_comment(),
276 doc: prelude.take_doc(),
277 name,
278 id,
279 args,
280 ok,
281 err,
282 }
283 }
284
285 fn validate(&self, validate: &mut Validate) {
286 BrokenDocLink::validate(&self.doc, validate);
287 NonSnakeCaseFunction::validate(self, validate);
288 InvalidFunctionId::validate(self, validate);
289
290 self.name.validate(true, validate);
291
292 if let Some(ref args) = self.args {
293 args.validate(validate);
294 }
295
296 if let Some(ref ok) = self.ok {
297 ok.validate(validate);
298 }
299
300 if let Some(ref err) = self.err {
301 err.validate(validate);
302 }
303 }
304
305 pub fn span(&self) -> Span {
306 self.span
307 }
308
309 pub fn comment(&self) -> &[Comment] {
310 &self.comment
311 }
312
313 pub fn doc(&self) -> &[DocString] {
314 &self.doc
315 }
316
317 pub fn name(&self) -> &Ident {
318 &self.name
319 }
320
321 pub fn id(&self) -> &LitInt {
322 &self.id
323 }
324
325 pub fn args(&self) -> Option<&FunctionPart> {
326 self.args.as_ref()
327 }
328
329 pub fn ok(&self) -> Option<&FunctionPart> {
330 self.ok.as_ref()
331 }
332
333 pub fn err(&self) -> Option<&FunctionPart> {
334 self.err.as_ref()
335 }
336}
337
338#[derive(Debug, Clone)]
339pub struct FunctionPart {
340 span: Span,
341 comment: Vec<Comment>,
342 part_type: TypeNameOrInline,
343}
344
345impl FunctionPart {
346 fn parse(pair: Pair<Rule>) -> Self {
347 let span = Span::from_pair(&pair);
348
349 let (comment, part_type) = match pair.as_rule() {
350 Rule::fn_args | Rule::fn_ok | Rule::fn_err => {
351 let mut pairs = pair.into_inner();
352 let mut prelude = Prelude::regular(&mut pairs);
353
354 pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
358 (prelude.take_comment(), TypeNameOrInline::parse(pair))
359 }
360
361 Rule::type_name_or_inline => (Vec::new(), TypeNameOrInline::parse(pair)),
362 _ => unreachable!(),
363 };
364
365 Self {
366 span,
367 comment,
368 part_type,
369 }
370 }
371
372 fn validate(&self, validate: &mut Validate) {
373 self.part_type.validate(validate);
374 }
375
376 pub fn span(&self) -> Span {
377 self.span
378 }
379
380 pub fn comment(&self) -> &[Comment] {
381 &self.comment
382 }
383
384 pub fn part_type(&self) -> &TypeNameOrInline {
385 &self.part_type
386 }
387}
388
389#[derive(Debug, Clone)]
390pub struct EventDef {
391 span: Span,
392 comment: Vec<Comment>,
393 doc: Vec<DocString>,
394 name: Ident,
395 id: LitInt,
396 event_type: Option<TypeNameOrInline>,
397}
398
399impl EventDef {
400 fn parse(pair: Pair<Rule>) -> Self {
401 assert_eq!(pair.as_rule(), Rule::event_def);
402
403 let span = Span::from_pair(&pair);
404 let mut pairs = pair.into_inner();
405 let mut prelude = Prelude::regular(&mut pairs);
406
407 pairs.next().unwrap(); let pair = pairs.next().unwrap();
410 let name = Ident::parse(pair);
411
412 pairs.next().unwrap(); let pair = pairs.next().unwrap();
415 let id = LitInt::parse(pair);
416
417 let pair = pairs.next().unwrap();
418 let event_type = match pair.as_rule() {
419 Rule::tok_eq => {
420 let pair = pairs.next().unwrap();
421 Some(TypeNameOrInline::parse(pair))
422 }
423
424 Rule::tok_term => None,
425 _ => unreachable!(),
426 };
427
428 Self {
429 span,
430 comment: prelude.take_comment(),
431 doc: prelude.take_doc(),
432 name,
433 id,
434 event_type,
435 }
436 }
437
438 fn validate(&self, validate: &mut Validate) {
439 BrokenDocLink::validate(&self.doc, validate);
440 NonSnakeCaseEvent::validate(self, validate);
441 InvalidEventId::validate(self, validate);
442
443 self.name.validate(true, validate);
444
445 if let Some(ref event_type) = self.event_type {
446 event_type.validate(validate);
447 }
448 }
449
450 pub fn span(&self) -> Span {
451 self.span
452 }
453
454 pub fn comment(&self) -> &[Comment] {
455 &self.comment
456 }
457
458 pub fn doc(&self) -> &[DocString] {
459 &self.doc
460 }
461
462 pub fn name(&self) -> &Ident {
463 &self.name
464 }
465
466 pub fn id(&self) -> &LitInt {
467 &self.id
468 }
469
470 pub fn event_type(&self) -> Option<&TypeNameOrInline> {
471 self.event_type.as_ref()
472 }
473}
474
475#[derive(Debug, Clone)]
476pub struct FunctionFallback {
477 span: Span,
478 comment: Vec<Comment>,
479 doc: Vec<DocString>,
480 name: Ident,
481}
482
483impl FunctionFallback {
484 fn parse(pair: Pair<Rule>) -> Self {
485 assert_eq!(pair.as_rule(), Rule::fn_fallback);
486
487 let span = Span::from_pair(&pair);
488 let mut pairs = pair.into_inner();
489 let mut prelude = Prelude::regular(&mut pairs);
490
491 pairs.next().unwrap(); let pair = pairs.next().unwrap();
494 let name = Ident::parse(pair);
495
496 Self {
497 span,
498 comment: prelude.take_comment(),
499 doc: prelude.take_doc(),
500 name,
501 }
502 }
503
504 fn validate(&self, validate: &mut Validate) {
505 self.name.validate(true, validate);
506
507 BrokenDocLink::validate(&self.doc, validate);
508 }
509
510 pub fn span(&self) -> Span {
511 self.span
512 }
513
514 pub fn comment(&self) -> &[Comment] {
515 &self.comment
516 }
517
518 pub fn doc(&self) -> &[DocString] {
519 &self.doc
520 }
521
522 pub fn name(&self) -> &Ident {
523 &self.name
524 }
525}
526
527#[derive(Debug, Clone)]
528pub struct EventFallback {
529 span: Span,
530 comment: Vec<Comment>,
531 doc: Vec<DocString>,
532 name: Ident,
533}
534
535impl EventFallback {
536 fn parse(pair: Pair<Rule>) -> Self {
537 assert_eq!(pair.as_rule(), Rule::event_fallback);
538
539 let span = Span::from_pair(&pair);
540 let mut pairs = pair.into_inner();
541 let mut prelude = Prelude::regular(&mut pairs);
542
543 pairs.next().unwrap(); let pair = pairs.next().unwrap();
546 let name = Ident::parse(pair);
547
548 Self {
549 span,
550 comment: prelude.take_comment(),
551 doc: prelude.take_doc(),
552 name,
553 }
554 }
555
556 fn validate(&self, validate: &mut Validate) {
557 self.name.validate(true, validate);
558
559 BrokenDocLink::validate(&self.doc, validate);
560 }
561
562 pub fn span(&self) -> Span {
563 self.span
564 }
565
566 pub fn comment(&self) -> &[Comment] {
567 &self.comment
568 }
569
570 pub fn doc(&self) -> &[DocString] {
571 &self.doc
572 }
573
574 pub fn name(&self) -> &Ident {
575 &self.name
576 }
577}