mist_parser/parser/items/
function.rs1use 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}