diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 9bd3207..ebc85b3 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -211,11 +211,9 @@ impl From> for ClassConstructor { let visibility = Visibility::from(&mut inner); - let params = if inner.peek().unwrap().as_rule() == Rule::param_list { - ParamList::from(inner.next().unwrap()) - } else { - ParamList(Vec::new()) - }; + let params = consume_rule(&mut inner, Rule::param_list) + .map(ParamList::from) + .unwrap_or_else(|| ParamList(Vec::new())); Self { visibility, @@ -394,18 +392,8 @@ impl From> for Expression { } Rule::primary => Expression::from(inner.next().unwrap()), Rule::static_path => Expression::Path(Path::from(pair)), - Rule::integer => { - Expression::Literal(Literal::Int(pair.as_str().parse::().unwrap())) - } - Rule::float => { - Expression::Literal(Literal::Float(pair.as_str().parse::().unwrap())) - } - Rule::boolean => { - Expression::Literal(Literal::Bool(pair.as_str().parse::().unwrap())) - } - Rule::string_lit => Expression::Literal(Literal::String(inner.as_str().to_string())), - Rule::tuple => { - Expression::Literal(Literal::Tuple(inner.map(Expression::from).collect())) + Rule::integer | Rule::float | Rule::boolean | Rule::string_lit | Rule::tuple => { + Expression::Literal(Literal::from(pair)) } _ => unimplemented!("{rule:#?}"), } @@ -539,15 +527,15 @@ impl From> for FunctionDecl { let return_type = TypeExpr::from(inner.next().unwrap()); let name = inner.next().unwrap().as_str().to_string(); - let self_param = if inner.peek().unwrap().as_rule() == Rule::self_param { - let mut param = inner.next().unwrap().into_inner(); + let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| { + let mut param_inner = param.into_inner(); let name = format!("self"); - let mutable = listen_rule(&mut param, Rule::mutable); + let mutable = listen_rule(&mut param_inner, Rule::mutable); - let is_ref = listen_rule(&mut param, Rule::deref_px); + let is_ref = listen_rule(&mut param_inner, Rule::deref_px); - Some(VarDecl { + VarDecl { mutable: mutable && !is_ref, name, type_: Some(TypeExpr( @@ -562,20 +550,21 @@ impl From> for FunctionDecl { Vec::new() }, )), - }) - } else { - None - }; - - let params = if inner.peek().unwrap().as_rule() == Rule::param_list { - let mut params = ParamList::from(inner.next().unwrap()); - if let Some(x) = self_param { - params.0.insert(0, x); } - params - } else { - ParamList(self_param.into_iter().collect()) - }; + }); + + let params = consume_rule(&mut inner, Rule::param_list) + .map({ + let self_param = self_param.clone(); + |params_pair| { + let mut params = ParamList::from(params_pair); + if let Some(x) = self_param { + params.0.insert(0, x); + } + params + } + }) + .unwrap_or_else(|| ParamList(self_param.into_iter().collect())); let body = Block::from(inner.next().unwrap()); @@ -611,3 +600,15 @@ pub fn listen_rule(pairs: &mut pest::iterators::Pairs<'_, Rule>, rule: Rule) -> consumed } + +pub fn consume_rule<'a>( + pairs: &mut pest::iterators::Pairs<'a, Rule>, + rule: Rule, +) -> Option> { + let consumed = pairs + .peek() + .map(|p| p.as_rule() == rule) + .unwrap_or_default(); + + if consumed { pairs.next() } else { None } +}