Skip to main content

mist_parser/parser/common/
types.rs

1use crate::{
2    Rule,
3    ast::*,
4    ast_ensure, ast_expr,
5    error::{AstError, AstResult, IntoErr, collect_recovered},
6    parser::{consume_rule, listen_rule},
7};
8
9impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
10    type Error = AstError<'a, Self>;
11
12    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
13        let rule = pair.as_rule();
14        let mut inner = pair.clone().into_inner();
15
16        match rule {
17            Rule::generic => Self::try_from(inner.next().unwrap()),
18            Rule::type_expr => inner.next().unwrap().try_into(),
19            Rule::lifetime => ast_expr!(TypeExpr::Lifetime(inner.next().unwrap().try_into())),
20
21            Rule::tuple_type => ast_expr!(TypeExpr::Tuple(collect_recovered(inner))),
22            Rule::path_type => {
23                ast_expr!(TypeExpr::Path(
24                    Path::try_from(inner.next().unwrap()),
25                    inner.next().map(Generics::try_from).transpose()
26                ))
27            }
28
29            Rule::ref_type => {
30                ast_expr!(TypeExpr::Ref {
31                    lifetime: consume_rule(&mut inner, Rule::lifetime)
32                        .map(|v| v.into_inner().next().map(Identifier::try_from))
33                        .unwrap_or_default()
34                        .transpose(),
35                    mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<bool>,
36                    ty: TypeExpr::try_from(inner.next().unwrap()).map(Box::new),
37                })
38            }
39            Rule::dyn_type => {
40                ast_expr!(TypeExpr::Dyn(
41                    TypeExpr::try_from(inner.next().unwrap()).map(Box::new),
42                ))
43            }
44
45            _ => AstError::bug_unimplemented(pair),
46        }
47    }
48}
49
50impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericsDecl {
51    type Error = AstError<'a, Self>;
52
53    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
54        let inner = pair.clone().into_inner();
55
56        ast_ensure!(pair, Rule::generics_decl => {
57            ast_expr!(GenericsDecl(collect_recovered(inner)))
58        })
59    }
60}
61
62impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericDecl {
63    type Error = AstError<'a, Self>;
64
65    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
66        let mut inner = pair.clone().into_inner();
67
68        ast_ensure!(pair, Rule::generic_decl => {
69            if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
70                ast_expr!(GenericDecl::Lifetime(
71                    pair.into_inner().next().unwrap().try_into(),
72                ))
73            } else {
74                ast_expr!(GenericDecl::Type(
75                    inner.next().unwrap().try_into(),
76                    collect_recovered(inner),
77                ))
78            }
79        })
80    }
81}
82
83impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generics {
84    type Error = AstError<'a, Self>;
85
86    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
87        let inner = pair.clone().into_inner();
88
89        ast_ensure!(pair, Rule::generics => {
90            ast_expr!(Generics(collect_recovered(inner)))
91        })
92    }
93}
94
95impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generic {
96    type Error = AstError<'a, Self>;
97
98    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
99        let mut inner = pair.clone().into_inner();
100
101        ast_ensure!(pair, Rule::generic => {
102            if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
103                ast_expr!(Generic::Lifetime(
104                    pair.into_inner().next().unwrap().try_into(),
105                ))
106            } else {
107                ast_expr!(Generic::Type(
108                    inner.next().unwrap().try_into()
109                ))
110            }
111        })
112    }
113}