Propagate errors properly (reduce unwrap() calls)

This commit is contained in:
ConnorSkees 2020-01-17 21:42:51 -05:00
parent 02d6a511a5
commit 8076125576
2 changed files with 26 additions and 22 deletions

View File

@ -229,7 +229,7 @@ struct StyleSheetParser<'a> {
impl<'a> StyleSheetParser<'a> {
fn parse_toplevel(mut self) -> SassResult<StyleSheet> {
let mut rules = Vec::new();
let mut rules: Vec<Stmt> = Vec::new();
while let Some(Token { kind, .. }) = self.lexer.peek() {
match kind.clone() {
TokenKind::Ident(_)
@ -300,7 +300,9 @@ impl<'a> StyleSheetParser<'a> {
fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> {
let mut stmts = Vec::new();
while let Ok(tok) = eat_expr(&mut self.lexer, scope, super_selector) {
while let Some(tok) = eat_expr(&mut self.lexer, scope, super_selector)
.unwrap_or_else(|error| self.error(error.0, error.1))
{
match tok {
Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::MixinDecl(name, mixin) => {
@ -383,7 +385,7 @@ fn eat_include<I: Iterator<Item = Token>>(
};
let rules = mixin
.call_with_args(&args)
.eval(super_selector, &mut scope.clone());
.eval(super_selector, &mut scope.clone())?;
Ok(rules)
}
@ -482,23 +484,25 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>,
scope: &Scope,
super_selector: &Selector,
) -> Result<Expr, ()> {
) -> Result<Option<Expr>, (Pos, &'static str)> {
let mut values = Vec::with_capacity(5);
while let Some(tok) = toks.peek() {
match &tok.kind {
TokenKind::Symbol(Symbol::SemiColon) | TokenKind::Symbol(Symbol::CloseCurlyBrace) => {
toks.next();
devour_whitespace(toks);
return Ok(Expr::Style(Style::from_tokens(&values, scope)?));
return Ok(Some(Expr::Style(
Style::from_tokens(&values, scope).unwrap(),
)));
}
TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
toks.next();
devour_whitespace(toks);
return Ok(Expr::Selector(Selector::from_tokens(
return Ok(Some(Expr::Selector(Selector::from_tokens(
&mut values.iter().peekable(),
super_selector,
scope,
)));
))));
}
TokenKind::Variable(_) => {
let tok = toks.next().unwrap();
@ -512,10 +516,10 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
{
toks.next();
devour_whitespace(toks);
return Ok(Expr::VariableDecl(
return Ok(Some(Expr::VariableDecl(
name,
eat_variable_value(toks, scope).unwrap(), // .unwrap_or_else(|err| self.error(err.0, err.1)),
));
eat_variable_value(toks, scope)?
)));
} else {
values.push(Token {
kind: TokenKind::Variable(name),
@ -532,20 +536,20 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
};
devour_whitespace(toks);
if values.is_empty() {
return Ok(Expr::MultilineComment(s.clone()));
return Ok(Some(Expr::MultilineComment(s.clone())));
} else {
values.push(tok.clone())
}
}
TokenKind::AtRule(AtRule::Include) => {
return Ok(Expr::Include(
eat_include(toks, scope, super_selector).unwrap(),
));
return Ok(Some(Expr::Include(
eat_include(toks, scope, super_selector)?,
)));
}
TokenKind::AtRule(AtRule::Mixin) => {
toks.next();
let (name, mixin) = parse_mixin(toks, scope.clone()).unwrap();
return Ok(Expr::MixinDecl(name, mixin));
return Ok(Some(Expr::MixinDecl(name, mixin)));
}
TokenKind::AtRule(_) => {
if let Some(Token {
@ -554,7 +558,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
}) = toks.next()
{
if let Ok(a) = eat_at_rule(rule, pos, toks, scope) {
return Ok(a);
return Ok(Some(a));
}
}
}
@ -576,7 +580,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
}
};
}
Err(())
Ok(None)
}
/// Functions that print to stdout or stderr

View File

@ -1,7 +1,7 @@
use std::iter::Peekable;
use std::vec::IntoIter;
use crate::common::Scope;
use crate::common::{Pos, Scope};
use crate::function::{CallArgs, FuncArgs};
use crate::selector::Selector;
use crate::{eat_expr, Expr, RuleSet, Stmt, Token};
@ -39,16 +39,16 @@ impl Mixin {
self
}
pub fn eval(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> {
pub fn eval(&mut self, super_selector: &Selector, scope: &mut Scope) -> Result<Vec<Stmt>, (Pos, &'static str)> {
let mut stmts = Vec::new();
while let Ok(expr) = eat_expr(&mut self.body, scope, super_selector) {
while let Some(expr) = eat_expr(&mut self.body, scope, super_selector)? {
match expr {
Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::Include(_) => todo!(),
Expr::MixinDecl(_, _) => todo!(),
Expr::Selector(s) => {
self.nesting += 1;
let rules = self.eval(&super_selector.clone().zip(s.clone()), scope);
let rules = self.eval(&super_selector.clone().zip(s.clone()), scope)?;
stmts.push(Stmt::RuleSet(RuleSet {
super_selector: super_selector.clone(),
selector: s,
@ -67,6 +67,6 @@ impl Mixin {
Expr::MultilineComment(s) => stmts.push(Stmt::MultilineComment(s)),
}
}
stmts
Ok(stmts)
}
}