Skip to main content

mist_parser/
lib.rs

1use pest::Parser;
2use pest_derive::Parser;
3
4pub mod ast;
5
6use ast::*;
7
8#[derive(Parser)]
9#[grammar = "./src/grammar.pest"]
10pub struct MistParser;
11
12// convenience alias for pest errors
13pub type ParseError = pest::error::Error<Rule>;
14
15pub fn parse(source: &str) -> Result<Vec<TopLevel>, ParseError> {
16    let mut pairs = MistParser::parse(Rule::program, source)?;
17
18    let mut statements = vec![];
19
20    for pair in pairs.next().unwrap().into_inner() {
21        if pair.as_rule() != Rule::EOI {
22            statements.push(TopLevel::from(pair));
23        }
24    }
25
26    Ok(statements)
27}
28
29impl From<pest::iterators::Pair<'_, Rule>> for TypeExpr {
30    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
31        let rule = pair.as_rule();
32        let mut inner = pair.into_inner();
33
34        match rule {
35            Rule::type_expr => TypeExpr(
36                TypeExprKind::from(inner.next().unwrap()),
37                inner.map(TypePostfix::from).collect(),
38            ),
39            Rule::type_expr_param => TypeExpr::from(inner.next().unwrap()),
40            Rule::lifetime => TypeExpr(
41                TypeExprKind::Lifetime(Identifier::from(inner.next().unwrap())),
42                Vec::new(),
43            ),
44            _ => unimplemented!("{rule:#?}"),
45        }
46    }
47}
48
49impl From<pest::iterators::Pair<'_, Rule>> for TypePostfix {
50    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
51        let rule = pair.as_rule();
52        let mut inner = pair.into_inner();
53
54        match rule {
55            Rule::ref_type => {
56                let mutable = listen_rule(&mut inner, Rule::mutable);
57                let lifetime = consume_rule(&mut inner, Rule::lifetime)
58                    .map(|pair| Identifier::from(pair.into_inner().next().unwrap()));
59
60                if mutable {
61                    if let Some(lifetime) = lifetime {
62                        TypePostfix::RefMutLifetime(lifetime)
63                    } else {
64                        TypePostfix::RefMut
65                    }
66                } else {
67                    if let Some(lifetime) = lifetime {
68                        TypePostfix::RefLifetime(lifetime)
69                    } else {
70                        TypePostfix::Ref
71                    }
72                }
73            }
74            _ => unimplemented!("{rule:#?}"),
75        }
76    }
77}
78
79impl From<pest::iterators::Pair<'_, Rule>> for TypeExprKind {
80    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
81        let rule = pair.as_rule();
82        let mut inner = pair.into_inner();
83
84        match rule {
85            Rule::tuple_type => TypeExprKind::Tuple(inner.map(TypeExpr::from).collect()),
86            Rule::path_type => {
87                let path = Path::from(inner.next().unwrap());
88                let params = inner.map(TypeExpr::from).collect::<Vec<_>>();
89
90                if params.len() == 0 {
91                    TypeExprKind::Path(path)
92                } else {
93                    TypeExprKind::PathParams(path, params)
94                }
95            }
96            _ => unimplemented!("{rule:#?}"),
97        }
98    }
99}
100
101impl From<pest::iterators::Pair<'_, Rule>> for Path {
102    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
103        match pair.as_rule() {
104            Rule::static_path => Path(pair.into_inner().map(Identifier::from).collect()),
105            _ => unimplemented!("{pair:#?}"),
106        }
107    }
108}
109
110impl From<pest::iterators::Pair<'_, Rule>> for ParamList {
111    fn from(pair: pest::iterators::Pair<Rule>) -> Self {
112        ParamList(pair.into_inner().map(VarDecl::from).collect())
113    }
114}
115
116impl From<pest::iterators::Pair<'_, Rule>> for Attribute {
117    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
118        match pair.as_rule() {
119            Rule::attribute => {
120                // unwrap #[ ... ]
121                Attribute::from(pair.into_inner().next().unwrap())
122            }
123
124            Rule::meta => {
125                let mut inner = pair.into_inner();
126
127                // first item is always the path
128                let path = Path::from(inner.next().unwrap());
129
130                // check what comes next
131                match inner.next() {
132                    None => {
133                        // #[path]
134                        Attribute::Path(path)
135                    }
136
137                    Some(next) => match next.as_rule() {
138                        Rule::primary => {
139                            // #[path = literal]
140                            Attribute::NameValue {
141                                path,
142                                value: Literal::from(next),
143                            }
144                        }
145
146                        Rule::meta_list => {
147                            // #[path(...)]
148                            let items = next.into_inner().map(Attribute::from).collect();
149
150                            Attribute::List { path, items }
151                        }
152
153                        _ => unreachable!("unexpected rule in meta: {:?}", next.as_rule()),
154                    },
155                }
156            }
157
158            Rule::meta_list => {
159                // This case usually won't be hit directly,
160                // but it's nice to keep it safe if reused
161                let items = pair.into_inner().map(Attribute::from).collect::<Vec<_>>();
162
163                // NOTE: this shouldn't normally construct an Attribute alone
164                // but you can panic or wrap depending on your design
165                panic!("meta_list should be handled inside meta: {:?}", items);
166            }
167
168            _ => unreachable!("unexpected rule: {:?}", pair.as_rule()),
169        }
170    }
171}
172
173impl From<pest::iterators::Pair<'_, Rule>> for TopLevel {
174    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
175        let mut inner = pair.into_inner();
176
177        let attributes = inner
178            .next()
179            .unwrap()
180            .into_inner()
181            .map(Attribute::from)
182            .collect::<Vec<_>>();
183
184        TopLevel(
185            inner
186                .next()
187                .map(TopLevelKind::from)
188                .unwrap_or(TopLevelKind::ModAttribute),
189            attributes,
190        )
191    }
192}
193
194impl From<pest::iterators::Pair<'_, Rule>> for StatementBranch {
195    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
196        let mut inner = pair.into_inner();
197
198        let condition = Expression::from(inner.next().unwrap());
199        let body = Statement::from(inner.next().unwrap());
200
201        StatementBranch {
202            condition,
203            body: Box::new(body),
204        }
205    }
206}
207
208impl From<pest::iterators::Pair<'_, Rule>> for ClassConstructor {
209    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
210        let mut inner = pair.into_inner();
211
212        let visibility = Visibility::from(&mut inner);
213
214        let generics = consume_rule(&mut inner, Rule::generics)
215            .map(Generics::from)
216            .unwrap_or_default();
217
218        let params = consume_rule(&mut inner, Rule::param_list)
219            .map(ParamList::from)
220            .unwrap_or_else(|| ParamList(Vec::new()));
221
222        Self {
223            visibility,
224            generics,
225            params,
226            body: Block::from(inner.next().unwrap()),
227        }
228    }
229}
230
231impl From<pest::iterators::Pair<'_, Rule>> for Generics {
232    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
233        let rule = pair.as_rule();
234        let inner = pair.clone().into_inner();
235
236        match rule {
237            Rule::generics => Generics(
238                inner
239                    .map(|pair| {
240                        let mut inner = pair.into_inner();
241                        if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
242                            Generic::Lifetime(Identifier::from(pair.into_inner().next().unwrap()))
243                        } else {
244                            Generic::Type(
245                                Identifier::from(inner.next().unwrap()),
246                                inner.map(TypeExpr::from).collect(),
247                            )
248                        }
249                    })
250                    .collect(),
251            ),
252            _ => unimplemented!("{rule:#?}"),
253        }
254    }
255}
256
257impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
258    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
259        let rule = pair.as_rule();
260        let mut inner = pair.clone().into_inner();
261
262        match rule {
263            Rule::import => TopLevelKind::Import(Path::from(inner.next().unwrap())),
264
265            Rule::function_decl => TopLevelKind::FunctionDecl(FunctionDecl::from(pair)),
266
267            Rule::struct_decl => TopLevelKind::StructDecl {
268                visibility: Visibility::from(&mut inner),
269                name: Identifier::from(inner.next().unwrap()),
270                generics: consume_rule(&mut inner, Rule::generics)
271                    .map(Generics::from)
272                    .unwrap_or_default(),
273                fields: inner
274                    .next()
275                    .map(|pair| pair.into_inner().map(FieldDecl::from).collect())
276                    .unwrap_or_default(),
277            },
278
279            Rule::class_decl => TopLevelKind::ClassDecl {
280                visibility: Visibility::from(&mut inner),
281                name: Identifier::from(inner.next().unwrap()),
282                generics: consume_rule(&mut inner, Rule::generics)
283                    .map(Generics::from)
284                    .unwrap_or_default(),
285                fields: inner
286                    .next()
287                    .unwrap()
288                    .into_inner()
289                    .map(FieldDeclStmt::from)
290                    .collect(),
291                constructor: ClassConstructor::from(inner.next().unwrap()),
292                items: inner.into_iter().map(ClassItem::from).collect(),
293            },
294
295            Rule::enum_decl => TopLevelKind::EnumDecl {
296                visibility: Visibility::from(&mut inner),
297                name: Identifier::from(inner.next().unwrap()),
298                generics: consume_rule(&mut inner, Rule::generics)
299                    .map(Generics::from)
300                    .unwrap_or_default(),
301                fields: inner.map(EnumItem::from).collect(),
302            },
303
304            Rule::mod_package => TopLevelKind::Mod(Identifier::from(inner.next().unwrap())),
305
306            Rule::impl_for_decl | Rule::impl_decl => TopLevelKind::ImplDecl(ImplDecl::from(pair)),
307
308            Rule::trait_decl => TopLevelKind::TraitDecl {
309                visibility: Visibility::from(&mut inner),
310                name: Identifier::from(inner.next().unwrap()),
311                generics: consume_rule(&mut inner, Rule::generics)
312                    .map(Generics::from)
313                    .unwrap_or_default(),
314                requirements: consume_rule(&mut inner, Rule::trait_requirements)
315                    .map(|pair| pair.into_inner().map(TypeExpr::from).collect())
316                    .unwrap_or_default(),
317                items: inner.map(FunctionDecl::from).collect(),
318            },
319
320            _ => unimplemented!("{rule:#?}"),
321        }
322    }
323}
324
325impl From<pest::iterators::Pair<'_, Rule>> for ClassItem {
326    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
327        let rule = pair.as_rule();
328
329        match rule {
330            Rule::impl_decl | Rule::impl_for_decl => ClassItem::ImplDecl(ImplDecl::from(pair)),
331
332            Rule::method => ClassItem::Method(FunctionDecl::from(pair)),
333
334            _ => unimplemented!("{rule:#?}"),
335        }
336    }
337}
338
339impl From<pest::iterators::Pair<'_, Rule>> for ImplDecl {
340    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
341        let rule = pair.as_rule();
342        let mut inner = pair.clone().into_inner();
343
344        match rule {
345            Rule::impl_for_decl => ImplDecl {
346                generics: consume_rule(&mut inner, Rule::generics)
347                    .map(Generics::from)
348                    .unwrap_or_default(),
349                trait_: Some(TypeExpr::from(inner.next().unwrap())),
350                target: TypeExpr::from(inner.next().unwrap()),
351                methods: inner.map(FunctionDecl::from).collect(),
352            },
353
354            Rule::impl_decl => ImplDecl {
355                generics: consume_rule(&mut inner, Rule::generics)
356                    .map(Generics::from)
357                    .unwrap_or_default(),
358                trait_: None,
359                target: TypeExpr::from(inner.next().unwrap()),
360                methods: inner.map(FunctionDecl::from).collect(),
361            },
362
363            _ => unimplemented!("{rule:#?}"),
364        }
365    }
366}
367
368impl From<pest::iterators::Pair<'_, Rule>> for EnumItem {
369    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
370        let rule = pair.as_rule();
371        let mut inner = pair.clone().into_inner();
372
373        match rule {
374            Rule::enum_named => EnumItem::Named(Identifier::from(inner.next().unwrap())),
375
376            Rule::enum_tuple => EnumItem::Tuple(
377                Identifier::from(inner.next().unwrap()),
378                inner
379                    .next()
380                    .unwrap()
381                    .into_inner()
382                    .map(TypeExpr::from)
383                    .collect(),
384            ),
385
386            Rule::enum_struct => EnumItem::Struct(
387                Identifier::from(inner.next().unwrap()),
388                inner
389                    .next()
390                    .map(|pair| pair.into_inner().map(FieldDecl::from).collect())
391                    .unwrap_or_default(),
392            ),
393
394            _ => unimplemented!("{rule:#?}"),
395        }
396    }
397}
398
399impl From<pest::iterators::Pair<'_, Rule>> for Block {
400    fn from(pair: pest::iterators::Pair<Rule>) -> Self {
401        let statements = pair
402            .into_inner()
403            .flat_map(|pair| {
404                if pair.as_rule() == Rule::statement_list {
405                    pair.into_inner().map(Statement::from).collect()
406                } else {
407                    vec![Statement::from(pair)]
408                }
409            })
410            .collect();
411        Block(statements)
412    }
413}
414
415impl From<pest::iterators::Pair<'_, Rule>> for Statement {
416    fn from(pair: pest::iterators::Pair<Rule>) -> Self {
417        let rule = pair.as_rule();
418        let mut inner = pair.clone().into_inner();
419
420        match rule {
421            Rule::statement => Statement::from(inner.next().unwrap()),
422
423            Rule::expr_stmt => Statement::Expression(Expression::from(inner.next().unwrap())),
424
425            Rule::block => Statement::Block(Block::from(inner.next().unwrap())),
426
427            Rule::var_decl_statement => Statement::VarDecl(VarDeclStmt::from(pair)),
428
429            Rule::return_stmt => {
430                let expr = inner.next().map(Expression::from);
431
432                Statement::Return(expr)
433            }
434
435            Rule::break_stmt => Statement::Break,
436
437            Rule::continue_stmt => Statement::Continue,
438
439            Rule::if_stmt => {
440                let mut inner = inner.skip(2);
441
442                Statement::If {
443                    initial: pair.into(),
444                    else_if: inner
445                        .next()
446                        .unwrap()
447                        .into_inner()
448                        .map(StatementBranch::from)
449                        .collect(),
450                    else_branch: inner.next().map(Statement::from).map(Box::new),
451                }
452            }
453
454            Rule::while_stmt => Statement::While(pair.into()),
455
456            Rule::c_for_stmt => Statement::CStyleFor {
457                init: Box::new(Statement::from(inner.next().unwrap())),
458                condition: inner.next().unwrap().into(),
459                update: Box::new(Statement::from(inner.next().unwrap())),
460                body: Box::new(Statement::from(inner.next().unwrap())),
461            },
462
463            Rule::for_stmt => Statement::For {
464                mutable: listen_rule(&mut inner, Rule::mutable),
465                pattern: Pattern::from(inner.next().unwrap()),
466                iterator: inner.next().unwrap().into(),
467                body: Box::new(Statement::from(inner.next().unwrap())),
468            },
469
470            Rule::assign_statement => Statement::VarAssign(VarAssignStmt {
471                target: Expression::from(inner.next().unwrap()),
472                value: Expression::from(inner.next().unwrap()),
473            }),
474
475            Rule::match_stmt => Statement::Match(
476                Expression::from(inner.next().unwrap()),
477                inner
478                    .map(|match_itms| {
479                        let mut match_inner = match_itms.into_inner();
480                        (
481                            Pattern::from(match_inner.next().unwrap()),
482                            Block::from(match_inner.next().unwrap()),
483                        )
484                    })
485                    .collect(),
486            ),
487
488            _ => unimplemented!("{rule:#?}"),
489        }
490    }
491}
492
493impl From<pest::iterators::Pair<'_, Rule>> for Literal {
494    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
495        let rule = pair.as_rule();
496        let mut inner = pair.clone().into_inner();
497
498        match rule {
499            Rule::primary => Self::from(inner.next().unwrap()),
500            Rule::literal => Self::from(inner.next().unwrap()),
501            Rule::integer => Literal::Int(pair.as_str().parse::<i64>().unwrap()),
502            Rule::float => Literal::Float(pair.as_str().parse::<f64>().unwrap()),
503            Rule::boolean => Literal::Bool(pair.as_str().parse::<bool>().unwrap()),
504            Rule::string_lit => Literal::String(inner.as_str().to_string()),
505            Rule::tuple => Literal::Tuple(inner.map(Expression::from).collect()),
506            _ => unimplemented!("{rule:#?}"),
507        }
508    }
509}
510
511impl From<pest::iterators::Pair<'_, Rule>> for Expression {
512    fn from(pair: pest::iterators::Pair<Rule>) -> Self {
513        let rule = pair.as_rule();
514        let mut inner = pair.clone().into_inner();
515
516        match rule {
517            Rule::expr => {
518                let prefixes: Vec<Prefix> = inner
519                    .next()
520                    .map(|p| p.into_inner().into_iter().map(Prefix::from).collect())
521                    .unwrap_or_default();
522
523                let exp = Expression::from(inner.next().unwrap());
524
525                if inner.len() > 0 || prefixes.len() > 0 {
526                    Expression::Fix {
527                        initial: Box::new(exp),
528                        prefixes,
529                        postfixes: inner.map(|p| Postfix::from(p)).collect(),
530                    }
531                } else {
532                    exp
533                }
534            }
535            Rule::primary => Expression::from(inner.next().unwrap()),
536            Rule::static_path => Expression::Path(Path::from(pair)),
537            Rule::literal => Expression::Literal(Literal::from(pair)),
538            _ => unimplemented!("{rule:#?}"),
539        }
540    }
541}
542
543impl From<pest::iterators::Pair<'_, Rule>> for Prefix {
544    fn from(pair: pest::iterators::Pair<Rule>) -> Self {
545        match pair.as_rule() {
546            Rule::prefix => Self::from(pair.into_inner().next().unwrap()),
547            Rule::deref_px => Self::Deref,
548            Rule::mut_ref_px => Self::RefMut,
549            Rule::ref_px => Self::Ref,
550            Rule::new_px => Self::New,
551            Rule::not_px => Self::Not,
552            _ => unimplemented!("{pair:#?}"),
553        }
554    }
555}
556
557impl From<pest::iterators::Pair<'_, Rule>> for Postfix {
558    fn from(pair: pest::iterators::Pair<Rule>) -> Self {
559        let rule = pair.as_rule();
560        let mut inner = pair.into_inner();
561
562        match rule {
563            Rule::postfix => Postfix::from(inner.next().unwrap()),
564
565            Rule::field_px => Postfix::FieldAccess(Identifier::from(inner.next().unwrap())),
566
567            Rule::call_px => Postfix::Call(inner.map(Expression::from).collect()),
568
569            Rule::struct_px => Postfix::StructCall(
570                inner
571                    .map(|p| {
572                        let mut pi = p.into_inner();
573                        (
574                            Identifier::from(pi.next().unwrap()),
575                            Expression::from(pi.next().unwrap()),
576                        )
577                    })
578                    .collect(),
579            ),
580
581            Rule::index_px => Postfix::Index(Expression::from(inner.next().unwrap())),
582
583            Rule::binary_px => {
584                let op_pair = inner.next().unwrap();
585                let op = match op_pair.as_str() {
586                    "+" => BinaryOp::Plus,
587                    "-" => BinaryOp::Minus,
588                    "*" => BinaryOp::Multiply,
589                    "/" => BinaryOp::Divide,
590                    "%" => BinaryOp::Modulo,
591                    "==" => BinaryOp::Equal,
592                    "!=" => BinaryOp::NotEqual,
593                    "<" => BinaryOp::LessThan,
594                    ">" => BinaryOp::GreaterThan,
595                    "<=" => BinaryOp::LessThanOrEqual,
596                    ">=" => BinaryOp::GreaterThanOrEqual,
597                    "&&" => BinaryOp::And,
598                    "||" => BinaryOp::Or,
599
600                    _ => {
601                        unimplemented!("Binary operator not implemented yet: {}", op_pair.as_str())
602                    }
603                };
604                Postfix::Binary(op, Expression::from(inner.next().unwrap()))
605            }
606
607            Rule::macro_call_px => Postfix::MacroCall(inner.as_str().to_string()),
608
609            _ => unimplemented!("{rule:#?}"),
610        }
611    }
612}
613
614impl From<pest::iterators::Pair<'_, Rule>> for VarDeclStmt {
615    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
616        match pair.as_rule() {
617            Rule::var_decl_statement => {
618                let mut inner = pair.into_inner();
619
620                let decl = VarDecl::from(inner.next().unwrap());
621
622                let init = inner.next().map(Expression::from);
623
624                VarDeclStmt { decl, init }
625            }
626
627            _ => unimplemented!(),
628        }
629    }
630}
631
632impl From<pest::iterators::Pair<'_, Rule>> for FieldDeclStmt {
633    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
634        match pair.as_rule() {
635            Rule::class_field => {
636                let mut inner = pair.into_inner();
637
638                let decl = FieldDecl::from(inner.next().unwrap());
639
640                let init = inner.next().map(Expression::from);
641
642                FieldDeclStmt { decl, init }
643            }
644
645            _ => unimplemented!(),
646        }
647    }
648}
649
650impl From<pest::iterators::Pair<'_, Rule>> for Pattern {
651    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
652        let rule = pair.as_rule();
653        let mut inner = pair.clone().into_inner();
654
655        match rule {
656            Rule::tuple_pattern => Pattern::Tuple(inner.map(Identifier::from).collect()),
657
658            Rule::named_tuple_pattern => Pattern::NamedTuple(
659                Path::from(inner.next().unwrap()),
660                inner.map(Identifier::from).collect(),
661            ),
662
663            Rule::struct_pattern => Pattern::Struct(
664                Path::from(inner.next().unwrap()),
665                inner.map(Identifier::from).collect(),
666            ),
667
668            Rule::literal => Pattern::Literal(Literal::from(pair)),
669
670            Rule::identifier => Pattern::Id(Identifier::from(pair)),
671
672            Rule::static_path => Pattern::Path(Path::from(pair)),
673
674            _ => unimplemented!("{rule:?}"),
675        }
676    }
677}
678
679impl From<pest::iterators::Pair<'_, Rule>> for VarDecl {
680    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
681        match pair.as_rule() {
682            Rule::var_decl => {
683                let mut inner = pair.into_inner();
684
685                let type_ = inner.next().and_then(|pair| {
686                    if pair.as_str().trim() == "var" {
687                        None
688                    } else {
689                        Some(TypeExpr::from(pair))
690                    }
691                });
692                let mutable = listen_rule(&mut inner, Rule::mutable);
693
694                let name = Pattern::from(inner.next().unwrap());
695
696                VarDecl {
697                    mutable,
698                    name,
699                    type_,
700                }
701            }
702
703            _ => unimplemented!("{:?}", pair.as_rule()),
704        }
705    }
706}
707
708impl From<pest::iterators::Pair<'_, Rule>> for FieldDecl {
709    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
710        match pair.as_rule() {
711            Rule::field => {
712                let mut inner = pair.into_inner();
713
714                let visibility = Visibility::from(&mut inner);
715                let type_ = TypeExpr::from(inner.next().unwrap());
716                let name = Identifier::from(inner.next().unwrap());
717
718                FieldDecl {
719                    visibility,
720                    type_,
721                    name,
722                }
723            }
724
725            _ => unimplemented!("{:?}", pair.as_rule()),
726        }
727    }
728}
729
730impl From<pest::iterators::Pair<'_, Rule>> for FunctionDecl {
731    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
732        let mut inner = pair.into_inner();
733        let visibility = Visibility::from(&mut inner);
734        let return_type = TypeExpr::from(inner.next().unwrap());
735        let name = Identifier::from(inner.next().unwrap());
736        let generics = consume_rule(&mut inner, Rule::generics)
737            .map(Generics::from)
738            .unwrap_or_default();
739
740        let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
741            let mut param_inner = param.into_inner();
742            let name = Pattern::Id(Identifier(String::from("self")));
743
744            let mutable = listen_rule(&mut param_inner, Rule::mutable);
745
746            let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
747
748            VarDecl {
749                mutable: mutable && !is_ref,
750                name: name.clone(),
751                type_: Some(TypeExpr(
752                    TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])),
753                    if is_ref {
754                        vec![if mutable {
755                            TypePostfix::RefMut
756                        } else {
757                            TypePostfix::Ref
758                        }]
759                    } else {
760                        Vec::new()
761                    },
762                )),
763            }
764        });
765
766        let params = consume_rule(&mut inner, Rule::param_list)
767            .map({
768                let self_param = self_param.clone();
769                |params_pair| {
770                    let mut params = ParamList::from(params_pair);
771                    if let Some(x) = self_param {
772                        params.0.insert(0, x);
773                    }
774                    params
775                }
776            })
777            .unwrap_or_else(|| ParamList(self_param.into_iter().collect()));
778
779        let body = inner.next().map(Block::from);
780
781        Self {
782            visibility,
783            name,
784            generics,
785            params,
786            return_type,
787            body,
788        }
789    }
790}
791
792impl From<&mut pest::iterators::Pairs<'_, Rule>> for Visibility {
793    fn from(pairs: &mut pest::iterators::Pairs<'_, Rule>) -> Self {
794        if listen_rule(pairs, Rule::export) {
795            Visibility::Public
796        } else {
797            Visibility::Private
798        }
799    }
800}
801
802pub fn listen_rule(pairs: &mut pest::iterators::Pairs<'_, Rule>, rule: Rule) -> bool {
803    let consumed = pairs
804        .peek()
805        .map(|p| p.as_rule() == rule)
806        .unwrap_or_default();
807
808    if consumed {
809        pairs.next();
810    }
811
812    consumed
813}
814
815pub fn consume_rule<'a>(
816    pairs: &mut pest::iterators::Pairs<'a, Rule>,
817    rule: Rule,
818) -> Option<pest::iterators::Pair<'a, Rule>> {
819    let consumed = pairs
820        .peek()
821        .map(|p| p.as_rule() == rule)
822        .unwrap_or_default();
823
824    if consumed { pairs.next() } else { None }
825}
826
827impl From<pest::iterators::Pair<'_, Rule>> for Identifier {
828    fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
829        Identifier(pair.as_str().to_string())
830    }
831}