aldrin_parser/ast/
service_def.rs

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(); // Skip keyword.
36
37        let pair = pairs.next().unwrap();
38        let name = Ident::parse(pair);
39
40        pairs.next().unwrap(); // Skip {.
41
42        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(); // Skip keyword.
93        pairs.next().unwrap(); // Skip =.
94
95        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(); // Skip keyword.
106        pairs.next().unwrap(); // Skip =.
107
108        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(); // Skip keyword.
249
250        let pair = pairs.next().unwrap();
251        let name = Ident::parse(pair);
252
253        pairs.next().unwrap(); // Skip @.
254
255        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(); // Skip keyword.
355                pairs.next().unwrap(); // Skip =.
356
357                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(); // Skip keyword.
408
409        let pair = pairs.next().unwrap();
410        let name = Ident::parse(pair);
411
412        pairs.next().unwrap(); // Skip @.
413
414        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(); // Skip keyword.
492
493        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(); // Skip keyword.
544
545        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}