Skip to main content

mist_parser/parser/common/
types.rs

1use crate::{
2    Rule,
3    ast::*,
4    ast_ensure, 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            Rule::dyn_type => Ok(TypePostfix::Dyn),
40
41            _ => AstError::bug_unimplemented(pair),
42        }
43    }
44}
45
46impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExprKind {
47    type Error = AstError<'a, Self>;
48
49    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
50        let rule = pair.as_rule();
51        let mut inner = pair.clone().into_inner();
52
53        match rule {
54            Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))),
55            Rule::path_type => {
56                let path = Path::try_from(inner.next().unwrap());
57                let params = collect_recovered(inner);
58
59                if params.len() == 0 {
60                    ast_expr!(TypeExprKind::Path(path))
61                } else {
62                    ast_expr!(TypeExprKind::PathParams(path, params))
63                }
64            }
65            _ => AstError::bug_unimplemented(pair),
66        }
67    }
68}
69
70impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
71    type Error = AstError<'a, Self>;
72
73    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
74        let rule = pair.as_rule();
75        let mut inner = pair.clone().into_inner();
76
77        match rule {
78            Rule::type_expr => ast_expr!(TypeExpr(
79                inner.next().unwrap().try_into(),
80                collect_recovered(inner),
81            )),
82            Rule::type_expr_param => Self::try_from(inner.next().unwrap()),
83            Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into()))
84                .get_map(TypeExpr::no_px)
85                .map(TypeExpr::no_px),
86
87            _ => AstError::bug_unimplemented(pair),
88        }
89    }
90}
91
92impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericsDecl {
93    type Error = AstError<'a, Self>;
94
95    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
96        let inner = pair.clone().into_inner();
97
98        ast_ensure!(pair, Rule::generics_decl => {
99            ast_expr!(GenericsDecl(collect_recovered(inner)))
100        })
101    }
102}
103
104impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericDecl {
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        ast_ensure!(pair, Rule::generic_decl => {
111            if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
112                ast_expr!(GenericDecl::Lifetime(
113                    pair.into_inner().next().unwrap().try_into(),
114                ))
115            } else {
116                ast_expr!(GenericDecl::Type(
117                    inner.next().unwrap().try_into(),
118                    collect_recovered(inner),
119                ))
120            }
121        })
122    }
123}
124
125impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generics {
126    type Error = AstError<'a, Self>;
127
128    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
129        let inner = pair.clone().into_inner();
130
131        ast_ensure!(pair, Rule::generics => {
132            ast_expr!(Generics(collect_recovered(inner)))
133        })
134    }
135}
136
137impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generic {
138    type Error = AstError<'a, Self>;
139
140    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
141        let mut inner = pair.clone().into_inner();
142
143        ast_ensure!(pair, Rule::generic => {
144            if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
145                ast_expr!(Generic::Lifetime(
146                    pair.into_inner().next().unwrap().try_into(),
147                ))
148            } else {
149                ast_expr!(Generic::Type(
150                    inner.next().unwrap().try_into()
151                ))
152            }
153        })
154    }
155}