Skip to main content

mist_parser/parser/common/
types.rs

1use crate::{
2    Rule,
3    ast::*,
4    ast_expr,
5    error::{AstError, GetLength, IntoErr, collect_recovered},
6    parser::{consume_rule, listen_rule},
7};
8
9impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypePostfix {
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::ref_type => {
18                let mutable = listen_rule(&mut inner, Rule::mutable);
19                let lifetime = consume_rule(&mut inner, Rule::lifetime)
20                    .map(|pair| Identifier::try_from(pair.into_inner().next().unwrap()))
21                    .transpose()
22                    .get()?;
23
24                Ok(if mutable {
25                    if let Some(lifetime) = lifetime {
26                        TypePostfix::RefMutLifetime(lifetime)
27                    } else {
28                        TypePostfix::RefMut
29                    }
30                } else {
31                    if let Some(lifetime) = lifetime {
32                        TypePostfix::RefLifetime(lifetime)
33                    } else {
34                        TypePostfix::Ref
35                    }
36                })
37            }
38
39            _ => AstError::bug_unimplemented(pair),
40        }
41    }
42}
43
44impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExprKind {
45    type Error = AstError<'a, Self>;
46
47    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
48        let rule = pair.as_rule();
49        let mut inner = pair.clone().into_inner();
50
51        match rule {
52            Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))),
53            Rule::path_type => {
54                let path = Path::try_from(inner.next().unwrap());
55                let params = collect_recovered(inner);
56
57                if params.len() == 0 {
58                    ast_expr!(TypeExprKind::Path(path))
59                } else {
60                    ast_expr!(TypeExprKind::PathParams(path, params))
61                }
62            }
63            _ => AstError::bug_unimplemented(pair),
64        }
65    }
66}
67
68impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
69    type Error = AstError<'a, Self>;
70
71    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
72        let rule = pair.as_rule();
73        let mut inner = pair.clone().into_inner();
74
75        match rule {
76            Rule::type_expr => ast_expr!(TypeExpr(
77                inner.next().unwrap().try_into(),
78                collect_recovered(inner),
79            )),
80            Rule::type_expr_param => Self::try_from(inner.next().unwrap()),
81            Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into()))
82                .get_map(TypeExpr::no_px)
83                .map(TypeExpr::no_px),
84
85            _ => AstError::bug_unimplemented(pair),
86        }
87    }
88}
89
90impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generics {
91    type Error = AstError<'a, Self>;
92
93    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
94        let rule = pair.as_rule();
95        let inner = pair.clone().into_inner();
96
97        match rule {
98            Rule::generics => ast_expr!(Generics(collect_recovered(inner))),
99            _ => AstError::bug_unimplemented(pair),
100        }
101    }
102}
103
104impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generic {
105    type Error = AstError<'a, Self>;
106
107    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
108        let mut inner = pair.clone().into_inner();
109
110        if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
111            ast_expr!(Generic::Lifetime(
112                pair.into_inner().next().unwrap().try_into(),
113            ))
114        } else {
115            ast_expr!(Generic::Type(
116                inner.next().unwrap().try_into(),
117                collect_recovered(inner),
118            ))
119        }
120    }
121}