Skip to main content

mist_parser/parser/items/
mod.rs

1pub mod attribute;
2pub mod class;
3pub mod enums;
4pub mod function;
5pub mod impl_decl;
6
7use crate::{
8    Rule,
9    ast::*,
10    ast_expr,
11    error::{AstError, IntoErr, collect_recovered},
12    parser::consume_rule,
13};
14
15impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevel {
16    type Error = AstError<'a, Self>;
17
18    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
19        let mut inner = pair.into_inner();
20
21        let attributes = collect_recovered(inner.next().unwrap().into_inner());
22
23        ast_expr!(TopLevel(
24            inner
25                .next()
26                .map(TopLevelKind::try_from)
27                .unwrap_or(Ok(TopLevelKind::ModAttribute)),
28            attributes,
29        ))
30    }
31}
32
33impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
34    type Error = AstError<'a, Self>;
35
36    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
37        let rule = pair.as_rule();
38        let mut inner = pair.clone().into_inner();
39
40        match rule {
41            Rule::import => ast_expr!(TopLevelKind::Import(
42                Visibility::try_from(&mut inner),
43                Path::try_from(inner.next().unwrap()),
44            )),
45
46            Rule::function_decl => ast_expr!(TopLevelKind::FunctionDecl(pair.try_into())),
47
48            Rule::struct_decl => ast_expr!(TopLevelKind::StructDecl {
49                visibility: Visibility::try_from(&mut inner),
50
51                name: inner.next().unwrap().try_into(),
52
53                generics: consume_rule(&mut inner, Rule::generics)
54                    .map(Generics::try_from)
55                    .transpose()
56                    .map(|v| v.unwrap_or_default()),
57
58                fields: inner
59                    .next()
60                    .map(|pair| collect_recovered::<FieldDecl, FieldDecl>(pair.into_inner()))
61                    .transpose()
62                    .map(|v| v.unwrap_or_default()),
63            }),
64
65            Rule::class_decl => ast_expr!(TopLevelKind::ClassDecl {
66                visibility: Visibility::try_from(&mut inner),
67
68                name: inner.next().unwrap().try_into(),
69
70                generics: consume_rule(&mut inner, Rule::generics)
71                    .map(Generics::try_from)
72                    .transpose()
73                    .map(|v| v.unwrap_or_default()),
74
75                fields: collect_recovered(inner.next().unwrap().into_inner()),
76
77                constructor: inner.next().unwrap().try_into(),
78
79                items: collect_recovered(inner),
80            }),
81
82            Rule::enum_decl => ast_expr!(TopLevelKind::EnumDecl {
83                visibility: Visibility::try_from(&mut inner),
84
85                name: inner.next().unwrap().try_into(),
86
87                generics: consume_rule(&mut inner, Rule::generics)
88                    .map(Generics::try_from)
89                    .transpose()
90                    .map(|v| v.unwrap_or_default()),
91
92                fields: collect_recovered(inner),
93            }),
94
95            Rule::mod_package => ast_expr!(TopLevelKind::Mod(
96                Visibility::try_from(&mut inner),
97                inner.next().unwrap().try_into(),
98            )),
99
100            Rule::impl_for_decl | Rule::impl_decl => {
101                ast_expr!(TopLevelKind::ImplDecl(pair.try_into()))
102            }
103
104            Rule::trait_decl => ast_expr!(TopLevelKind::TraitDecl {
105                visibility: Visibility::try_from(&mut inner),
106
107                name: inner.next().unwrap().try_into(),
108
109                generics: consume_rule(&mut inner, Rule::generics)
110                    .map(Generics::try_from)
111                    .transpose()
112                    .map(|v| v.unwrap_or_default()),
113
114                requirements: consume_rule(&mut inner, Rule::trait_requirements)
115                    .map(|pair| collect_recovered::<TypeExpr, TypeExpr>(pair.into_inner()))
116                    .transpose()
117                    .map(|v| v.unwrap_or_default()),
118
119                items: collect_recovered(inner),
120            }),
121
122            _ => AstError::bug_unimplemented(pair),
123        }
124    }
125}