mist_parser/parser/items/
function.rs1use 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 is_override = consume_rule(&mut inner, Rule::override_kw).map(Override::try_from).transpose();
17 let name = Identifier::try_from(inner.next().unwrap());
18
19 let generics = consume_rule(&mut inner, Rule::generics_decl)
20 .map(GenericsDecl::try_from)
21 .transpose()
22 .map(|v| v.unwrap_or_default());
23
24 let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
25 let mut param_inner = param.into_inner();
26 let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
27 let lifetime = consume_rule(&mut param_inner, Rule::lifetime);
28 let mutable = listen_rule(&mut param_inner, Rule::mutable);
29 let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
30 let self_ty = TypeExpr::Path(Path(vec![Identifier(String::from("Self"))]), None);
31
32 VarDecl {
33 name: name.clone(),
34 type_: Some(if is_ref {
35 TypeExpr::Ref {
36 lifetime:
37 lifetime.map(|v| Identifier::try_from(v.into_inner().next().unwrap()))
38 .transpose()
39 .expect("Failed to get lifetime identifier"),
40 mutable,
41 ty: Box::new(self_ty)
42 }
43 } else {
44 self_ty
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 return_type = consume_rule(&mut inner, Rule::type_expr)
63 .map(TypeExpr::try_from)
64 .transpose();
65
66 let body = inner.next().map(Block::try_from).transpose();
67
68 ast_expr!(Self {
69 visibility: visibility,
70 is_override: is_override,
71 return_type: return_type,
72 name: name,
73 generics: generics,
74 params: params,
75 body: body,
76 })
77 })
78 }
79}
80
81impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Override {
82 type Error = AstError<'a, Self>;
83
84 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
85 ast_ensure!(pair, Rule::override_kw => {
86 ast_expr!(Override(pair.into_inner().next().map(ExprPath::try_from).transpose()))
87 })
88 }
89}