aldrin_parser/ast/
service_def.rs

1use super::{Ident, LitPosInt, LitUuid, TypeNameOrInline};
2use crate::error::{
3    DuplicateEventId, DuplicateFunctionId, DuplicateServiceItem, InvalidEventId, InvalidFunctionId,
4    InvalidServiceUuid, InvalidServiceVersion,
5};
6use crate::grammar::Rule;
7use crate::validate::Validate;
8use crate::warning::{NonCamelCaseService, NonSnakeCaseEvent, NonSnakeCaseFunction};
9use crate::Span;
10use pest::iterators::Pair;
11
12#[derive(Debug, Clone)]
13pub struct ServiceDef {
14    span: Span,
15    name: Ident,
16    uuid: LitUuid,
17    ver: LitPosInt,
18    items: Vec<ServiceItem>,
19    fn_fallback: Option<FunctionFallbackDef>,
20    ev_fallback: Option<EventFallbackDef>,
21}
22
23impl ServiceDef {
24    pub(crate) fn parse(pair: Pair<Rule>) -> Self {
25        assert_eq!(pair.as_rule(), Rule::service_def);
26
27        let span = Span::from_pair(&pair);
28
29        let mut pairs = pair.into_inner();
30        pairs.next().unwrap(); // Skip keyword.
31
32        let pair = pairs.next().unwrap();
33        let name = Ident::parse(pair);
34
35        pairs.next().unwrap(); // Skip {.
36
37        let pair = pairs.next().unwrap();
38        let uuid = Self::parse_uuid(pair);
39
40        let pair = pairs.next().unwrap();
41        let ver = Self::parse_version(pair);
42
43        let mut items = Vec::new();
44        let mut fn_fallback = None;
45        let mut ev_fallback = None;
46
47        for pair in pairs {
48            match pair.as_rule() {
49                Rule::service_item => items.push(ServiceItem::parse(pair)),
50
51                Rule::service_fallback => {
52                    for pair in pair.into_inner() {
53                        match pair.as_rule() {
54                            Rule::fn_fallback => {
55                                fn_fallback = Some(FunctionFallbackDef::parse(pair))
56                            }
57
58                            Rule::event_fallback => {
59                                ev_fallback = Some(EventFallbackDef::parse(pair))
60                            }
61
62                            _ => unreachable!(),
63                        }
64                    }
65                }
66
67                Rule::tok_cur_close => break,
68                _ => unreachable!(),
69            }
70        }
71
72        Self {
73            span,
74            name,
75            uuid,
76            ver,
77            items,
78            fn_fallback,
79            ev_fallback,
80        }
81    }
82
83    fn parse_uuid(pair: Pair<Rule>) -> LitUuid {
84        assert_eq!(pair.as_rule(), Rule::service_uuid);
85        let mut pairs = pair.into_inner();
86        pairs.next().unwrap(); // Skip keyword.
87        pairs.next().unwrap(); // Skip =.
88        let pair = pairs.next().unwrap();
89        LitUuid::parse(pair)
90    }
91
92    fn parse_version(pair: Pair<Rule>) -> LitPosInt {
93        assert_eq!(pair.as_rule(), Rule::service_version);
94        let mut pairs = pair.into_inner();
95        pairs.next().unwrap(); // Skip keyword.
96        pairs.next().unwrap(); // Skip =.
97        let pair = pairs.next().unwrap();
98        LitPosInt::parse(pair)
99    }
100
101    pub(crate) fn validate(&self, validate: &mut Validate) {
102        InvalidServiceUuid::validate(self, validate);
103        InvalidServiceVersion::validate(self, validate);
104        DuplicateServiceItem::validate(self, validate);
105        DuplicateFunctionId::validate(self, validate);
106        DuplicateEventId::validate(self, validate);
107        NonCamelCaseService::validate(self, validate);
108
109        self.name.validate(validate);
110
111        for item in &self.items {
112            item.validate(validate);
113        }
114
115        if let Some(ref fn_fallback) = self.fn_fallback {
116            fn_fallback.validate(validate);
117        }
118
119        if let Some(ref ev_fallback) = self.ev_fallback {
120            ev_fallback.validate(validate);
121        }
122    }
123
124    pub fn span(&self) -> Span {
125        self.span
126    }
127
128    pub fn name(&self) -> &Ident {
129        &self.name
130    }
131
132    pub fn uuid(&self) -> &LitUuid {
133        &self.uuid
134    }
135
136    pub fn version(&self) -> &LitPosInt {
137        &self.ver
138    }
139
140    pub fn items(&self) -> &[ServiceItem] {
141        &self.items
142    }
143
144    pub fn function_fallback(&self) -> Option<&FunctionFallbackDef> {
145        self.fn_fallback.as_ref()
146    }
147
148    pub fn event_fallback(&self) -> Option<&EventFallbackDef> {
149        self.ev_fallback.as_ref()
150    }
151}
152
153#[derive(Debug, Clone)]
154pub enum ServiceItem {
155    Function(FunctionDef),
156    Event(EventDef),
157}
158
159impl ServiceItem {
160    fn parse(pair: Pair<Rule>) -> Self {
161        assert_eq!(pair.as_rule(), Rule::service_item);
162        let mut pairs = pair.into_inner();
163        let pair = pairs.next().unwrap();
164        match pair.as_rule() {
165            Rule::fn_def => Self::Function(FunctionDef::parse(pair)),
166            Rule::event_def => Self::Event(EventDef::parse(pair)),
167            _ => unreachable!(),
168        }
169    }
170
171    fn validate(&self, validate: &mut Validate) {
172        match self {
173            Self::Function(i) => i.validate(validate),
174            Self::Event(i) => i.validate(validate),
175        }
176    }
177
178    pub fn span(&self) -> Span {
179        match self {
180            Self::Function(i) => i.span(),
181            Self::Event(i) => i.span(),
182        }
183    }
184
185    pub fn name(&self) -> &Ident {
186        match self {
187            Self::Function(i) => i.name(),
188            Self::Event(i) => i.name(),
189        }
190    }
191}
192
193#[derive(Debug, Clone)]
194pub struct FunctionDef {
195    span: Span,
196    name: Ident,
197    id: LitPosInt,
198    args: Option<FunctionPart>,
199    ok: Option<FunctionPart>,
200    err: Option<FunctionPart>,
201}
202
203impl FunctionDef {
204    fn parse(pair: Pair<Rule>) -> Self {
205        assert_eq!(pair.as_rule(), Rule::fn_def);
206
207        let span = Span::from_pair(&pair);
208
209        let mut pairs = pair.into_inner();
210
211        pairs.next().unwrap(); // Skip keyword.
212
213        let pair = pairs.next().unwrap();
214        let name = Ident::parse(pair);
215
216        pairs.next().unwrap(); // Skip @.
217
218        let pair = pairs.next().unwrap();
219        let id = LitPosInt::parse(pair);
220
221        let mut args = None;
222        let mut ok = None;
223        let mut err = None;
224        for pair in pairs {
225            match pair.as_rule() {
226                Rule::fn_args => args = Some(FunctionPart::parse(pair)),
227                Rule::fn_ok => ok = Some(FunctionPart::parse(pair)),
228                Rule::fn_err => err = Some(FunctionPart::parse(pair)),
229                Rule::type_name_or_inline => ok = Some(FunctionPart::parse(pair)),
230
231                Rule::tok_cur_open | Rule::tok_cur_close | Rule::tok_eq | Rule::tok_term => {}
232                _ => unreachable!(),
233            }
234        }
235
236        Self {
237            span,
238            name,
239            id,
240            args,
241            ok,
242            err,
243        }
244    }
245
246    fn validate(&self, validate: &mut Validate) {
247        NonSnakeCaseFunction::validate(self, validate);
248        InvalidFunctionId::validate(self, validate);
249
250        self.name.validate(validate);
251
252        if let Some(ref args) = self.args {
253            args.validate(validate);
254        }
255
256        if let Some(ref ok) = self.ok {
257            ok.validate(validate);
258        }
259
260        if let Some(ref err) = self.err {
261            err.validate(validate);
262        }
263    }
264
265    pub fn span(&self) -> Span {
266        self.span
267    }
268
269    pub fn name(&self) -> &Ident {
270        &self.name
271    }
272
273    pub fn id(&self) -> &LitPosInt {
274        &self.id
275    }
276
277    pub fn args(&self) -> Option<&FunctionPart> {
278        self.args.as_ref()
279    }
280
281    pub fn ok(&self) -> Option<&FunctionPart> {
282        self.ok.as_ref()
283    }
284
285    pub fn err(&self) -> Option<&FunctionPart> {
286        self.err.as_ref()
287    }
288}
289
290#[derive(Debug, Clone)]
291pub struct FunctionPart {
292    span: Span,
293    part_type: TypeNameOrInline,
294}
295
296impl FunctionPart {
297    fn parse(pair: Pair<Rule>) -> Self {
298        let span = Span::from_pair(&pair);
299
300        let pair = if (pair.as_rule() == Rule::fn_args)
301            || (pair.as_rule() == Rule::fn_ok)
302            || (pair.as_rule() == Rule::fn_err)
303        {
304            let mut pairs = pair.into_inner();
305
306            pairs.next().unwrap(); // Skip keyword.
307            pairs.next().unwrap(); // Skip =.
308
309            pairs.next().unwrap()
310        } else if pair.as_rule() == Rule::type_name_or_inline {
311            pair
312        } else {
313            unreachable!()
314        };
315
316        let part_type = TypeNameOrInline::parse(pair);
317        Self { span, part_type }
318    }
319
320    fn validate(&self, validate: &mut Validate) {
321        self.part_type.validate(validate);
322    }
323
324    pub fn span(&self) -> Span {
325        self.span
326    }
327
328    pub fn part_type(&self) -> &TypeNameOrInline {
329        &self.part_type
330    }
331}
332
333#[derive(Debug, Clone)]
334pub struct EventDef {
335    span: Span,
336    name: Ident,
337    id: LitPosInt,
338    event_type: Option<TypeNameOrInline>,
339}
340
341impl EventDef {
342    fn parse(pair: Pair<Rule>) -> Self {
343        assert_eq!(pair.as_rule(), Rule::event_def);
344
345        let span = Span::from_pair(&pair);
346
347        let mut pairs = pair.into_inner();
348
349        pairs.next().unwrap(); // Skip keyword.
350
351        let pair = pairs.next().unwrap();
352        let name = Ident::parse(pair);
353
354        pairs.next().unwrap(); // Skip @.
355
356        let pair = pairs.next().unwrap();
357        let id = LitPosInt::parse(pair);
358
359        let pair = pairs.next().unwrap();
360        let event_type = match pair.as_rule() {
361            Rule::tok_eq => {
362                let pair = pairs.next().unwrap();
363                Some(TypeNameOrInline::parse(pair))
364            }
365            Rule::tok_term => None,
366            _ => unreachable!(),
367        };
368
369        Self {
370            span,
371            name,
372            id,
373            event_type,
374        }
375    }
376
377    fn validate(&self, validate: &mut Validate) {
378        NonSnakeCaseEvent::validate(self, validate);
379        InvalidEventId::validate(self, validate);
380
381        self.name.validate(validate);
382        if let Some(ref event_type) = self.event_type {
383            event_type.validate(validate);
384        }
385    }
386
387    pub fn span(&self) -> Span {
388        self.span
389    }
390
391    pub fn name(&self) -> &Ident {
392        &self.name
393    }
394
395    pub fn id(&self) -> &LitPosInt {
396        &self.id
397    }
398
399    pub fn event_type(&self) -> Option<&TypeNameOrInline> {
400        self.event_type.as_ref()
401    }
402}
403
404#[derive(Debug, Clone)]
405pub struct FunctionFallbackDef {
406    span: Span,
407    name: Ident,
408}
409
410impl FunctionFallbackDef {
411    fn parse(pair: Pair<Rule>) -> Self {
412        assert_eq!(pair.as_rule(), Rule::fn_fallback);
413
414        let span = Span::from_pair(&pair);
415
416        let mut pairs = pair.into_inner();
417
418        pairs.next().unwrap(); // Skip keyword.
419
420        let pair = pairs.next().unwrap();
421        let name = Ident::parse(pair);
422
423        Self { span, name }
424    }
425
426    fn validate(&self, validate: &mut Validate) {
427        self.name.validate(validate);
428    }
429
430    pub fn span(&self) -> Span {
431        self.span
432    }
433
434    pub fn name(&self) -> &Ident {
435        &self.name
436    }
437}
438
439#[derive(Debug, Clone)]
440pub struct EventFallbackDef {
441    span: Span,
442    name: Ident,
443}
444
445impl EventFallbackDef {
446    fn parse(pair: Pair<Rule>) -> Self {
447        assert_eq!(pair.as_rule(), Rule::event_fallback);
448
449        let span = Span::from_pair(&pair);
450
451        let mut pairs = pair.into_inner();
452
453        pairs.next().unwrap(); // Skip keyword.
454
455        let pair = pairs.next().unwrap();
456        let name = Ident::parse(pair);
457
458        Self { span, name }
459    }
460
461    fn validate(&self, validate: &mut Validate) {
462        self.name.validate(validate);
463    }
464
465    pub fn span(&self) -> Span {
466        self.span
467    }
468
469    pub fn name(&self) -> &Ident {
470        &self.name
471    }
472}