From 52bf3f0091a7e7ba2d3e6a927d3b099a200df846 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 20 Jun 2020 22:29:35 -0400 Subject: [PATCH] implement short circuiting for `and` --- src/parse/value.rs | 25 ++++++++++++++++++++----- tests/and.rs | 5 +++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/parse/value.rs b/src/parse/value.rs index 09fd33c..86fee64 100644 --- a/src/parse/value.rs +++ b/src/parse/value.rs @@ -895,11 +895,26 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> { .push(Value::String(op.to_string(), QuoteKind::None).span(op.span)); } else if let Some(left) = space_separated.pop() { self.whitespace(); - let right = self.single_value()?; - space_separated.push( - Value::BinaryOp(Box::new(left.node), op.node, Box::new(right.node)) - .span(left.span.merge(right.span)), - ); + if left.node.is_true(left.span)? { + let right = self.single_value()?; + space_separated.push( + Value::BinaryOp(Box::new(left.node), op.node, Box::new(right.node)) + .span(left.span.merge(right.span)), + ); + } else { + // we explicitly ignore errors here as a workaround for short circuiting + while let Some(value) = self.peek() { + if let Ok(Spanned { + node: IntermediateValue::Comma, + .. + }) = value + { + break; + } + self.next(); + } + space_separated.push(left); + } } else { return Err(("Expected expression.", op.span).into()); } diff --git a/tests/and.rs b/tests/and.rs index dd48b9f..a3d9e4a 100644 --- a/tests/and.rs +++ b/tests/and.rs @@ -51,3 +51,8 @@ test!( "a {\n color: 1 - AND;\n}\n", "a {\n color: 1-AND;\n}\n" ); +test!( + short_circuits_when_lhs_is_false, + "a {\n color: false and comparable(\"a\", \"b\");\n}\n", + "a {\n color: false;\n}\n" +);