Skip to main content

mist_parser/parser/common/
types.rs

1use crate::{
2    Rule,
3    ast::*,
4    ast_ensure, ast_expr,
5    error::{AstError, 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                ast_expr!(TypeExprKind::Path(
57                    Path::try_from(inner.next().unwrap()),
58                    inner.next().map(Generics::try_from).transpose()
59                ))
60            }
61            _ => AstError::bug_unimplemented(pair),
62        }
63    }
64}
65
66impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
67    type Error = AstError<'a, Self>;
68
69    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
70        let rule = pair.as_rule();
71        let mut inner = pair.clone().into_inner();
72
73        match rule {
74            Rule::generic => Self::try_from(inner.next().unwrap()),
75            Rule::type_expr => ast_expr!(TypeExpr(
76                inner.next().unwrap().try_into(),
77                collect_recovered(inner),
78            )),
79            Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into()))
80                .get_map(TypeExpr::no_px)
81                .map(TypeExpr::no_px),
82
83            _ => AstError::bug_unimplemented(pair),
84        }
85    }
86}
87
88impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericsDecl {
89    type Error = AstError<'a, Self>;
90
91    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
92        let inner = pair.clone().into_inner();
93
94        ast_ensure!(pair, Rule::generics_decl => {
95            ast_expr!(GenericsDecl(collect_recovered(inner)))
96        })
97    }
98}
99
100impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for GenericDecl {
101    type Error = AstError<'a, Self>;
102
103    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
104        let mut inner = pair.clone().into_inner();
105
106        ast_ensure!(pair, Rule::generic_decl => {
107            if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
108                ast_expr!(GenericDecl::Lifetime(
109                    pair.into_inner().next().unwrap().try_into(),
110                ))
111            } else {
112                ast_expr!(GenericDecl::Type(
113                    inner.next().unwrap().try_into(),
114                    collect_recovered(inner),
115                ))
116            }
117        })
118    }
119}
120
121impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generics {
122    type Error = AstError<'a, Self>;
123
124    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
125        let inner = pair.clone().into_inner();
126
127        ast_ensure!(pair, Rule::generics => {
128            ast_expr!(Generics(collect_recovered(inner)))
129        })
130    }
131}
132
133impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Generic {
134    type Error = AstError<'a, Self>;
135
136    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
137        let mut inner = pair.clone().into_inner();
138
139        ast_ensure!(pair, Rule::generic => {
140            if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) {
141                ast_expr!(Generic::Lifetime(
142                    pair.into_inner().next().unwrap().try_into(),
143                ))
144            } else {
145                ast_expr!(Generic::Type(
146                    inner.next().unwrap().try_into()
147                ))
148            }
149        })
150    }
151}