Skip to main content

mist_parser/parser/items/
function.rs

1use crate::{
2    Rule,
3    ast::*,
4    ast_ensure, ast_expr,
5    error::{AstError, AstResult, IntoErr},
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        ast_ensure!(pair, Rule::function_decl => {
14        let mut inner = pair.into_inner();
15            let visibility = Visibility::try_from(&mut inner);
16            let name = Identifier::try_from(inner.next().unwrap());
17
18            let generics = consume_rule(&mut inner, Rule::generics_decl)
19                .map(GenericsDecl::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 is_ref = listen_rule(&mut param_inner, Rule::deref_px);
26                let lifetime = consume_rule(&mut param_inner, Rule::lifetime);
27                let mutable = listen_rule(&mut param_inner, Rule::mutable);
28                let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
29                let self_ty = TypeExpr::Path(Path(vec![Identifier(String::from("Self"))]), None);
30
31                VarDecl {
32                    name: name.clone(),
33                    type_: Some(if is_ref {
34                        TypeExpr::Ref {
35                            lifetime:
36                                lifetime.map(|v| Identifier::try_from(v.into_inner().next().unwrap()))
37                                    .transpose()
38                                    .expect("Failed to get lifetime identifier"),
39                            mutable,
40                            ty: Box::new(self_ty)
41                        }
42                    } else {
43                        self_ty
44                    }),
45                }
46            });
47
48            let params = consume_rule(&mut inner, Rule::param_list)
49                .map({
50                    let self_param = self_param.clone();
51                    |params_pair| -> AstResult<'a, ParamList> {
52                        let mut params = ParamList::try_from(params_pair)?;
53                        if let Some(x) = self_param {
54                            params.0.insert(0, x);
55                        }
56                        Ok(params)
57                    }
58                })
59                .unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())));
60
61            let return_type = consume_rule(&mut inner, Rule::type_expr)
62                .map(TypeExpr::try_from)
63                .transpose();
64
65            let body = inner.next().map(Block::try_from).transpose();
66
67            ast_expr!(Self {
68                visibility: visibility,
69                return_type: return_type,
70                name: name,
71                generics: generics,
72                params: params,
73                body: body,
74            })
75        })
76    }
77}