Skip to main content

mist_parser/parser/items/
function.rs

1use crate::{
2    Rule,
3    ast::*,
4    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 FunctionDecl {
10    type Error = AstError<'a, Self>;
11
12    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
13        let mut inner = pair.into_inner();
14        let visibility = Visibility::try_from(&mut inner);
15        let return_type = TypeExpr::try_from(inner.next().unwrap());
16        let name = Identifier::try_from(inner.next().unwrap());
17
18        let generics = consume_rule(&mut inner, Rule::generics)
19            .map(Generics::try_from)
20            .transpose()
21            .map(|v| v.unwrap_or_default());
22
23        let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
24            let mut param_inner = param.into_inner();
25            let name = Pattern::Id(Identifier(String::from("self")));
26
27            let mutable = listen_rule(&mut param_inner, Rule::mutable);
28
29            let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
30
31            VarDecl {
32                mutable: mutable && !is_ref,
33                name: name.clone(),
34                type_: Some(TypeExpr(
35                    TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])),
36                    if is_ref {
37                        vec![if mutable {
38                            TypePostfix::RefMut
39                        } else {
40                            TypePostfix::Ref
41                        }]
42                    } else {
43                        Vec::new()
44                    },
45                )),
46            }
47        });
48
49        let params = consume_rule(&mut inner, Rule::param_list)
50            .map({
51                let self_param = self_param.clone();
52                |params_pair| -> AstResult<'a, ParamList> {
53                    let mut params = ParamList::try_from(params_pair)?;
54                    if let Some(x) = self_param {
55                        params.0.insert(0, x);
56                    }
57                    Ok(params)
58                }
59            })
60            .unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())));
61
62        let body = inner.next().map(Block::try_from).transpose();
63
64        ast_expr!(Self {
65            visibility: visibility,
66            return_type: return_type,
67            name: name,
68            generics: generics,
69            params: params,
70            body: body,
71        })
72    }
73}
74
75impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ParamList {
76    type Error = AstError<'a, Self>;
77
78    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
79        Ok(ParamList(collect_recovered(pair.into_inner()).get()?))
80    }
81}