diff --git a/jexl-eval/src/lib.rs b/jexl-eval/src/lib.rs index 55196c9..4622b35 100644 --- a/jexl-eval/src/lib.rs +++ b/jexl-eval/src/lib.rs @@ -257,6 +257,18 @@ impl<'a> Evaluator<'a> { .ok_or(EvaluationError::UnknownTransform(name))?; f(&args_arr).map_err(|e| e.into()) } + + Expression::Conditional { + left, + truthy, + falsy, + } => { + if self.eval_ast(*left, context)?.is_truthy() { + self.eval_ast(*truthy, context) + } else { + self.eval_ast(*falsy, context) + } + } } } } @@ -463,10 +475,12 @@ mod tests { } #[test] - #[should_panic] fn test_conditional_expression() { - assert_eq!(Evaluator::new().eval("'foo' ? 1 : 2").unwrap(), value!(1)); - assert_eq!(Evaluator::new().eval("'' ? 1 : 2").unwrap(), value!(2)); + assert_eq!( + Evaluator::new().eval("'foo' ? 1 : 2").unwrap(), + value!(1f64) + ); + assert_eq!(Evaluator::new().eval("'' ? 1 : 2").unwrap(), value!(2f64)); } #[test] diff --git a/jexl-parser/src/ast.rs b/jexl-parser/src/ast.rs index 7f30b28..46c7ead 100644 --- a/jexl-parser/src/ast.rs +++ b/jexl-parser/src/ast.rs @@ -9,6 +9,8 @@ pub enum Expression { Boolean(bool), Array(Vec>), Object(Vec<(String, Box)>), + Identifier(String), + BinaryOperation { operation: OpCode, left: Box, @@ -28,7 +30,11 @@ pub enum Expression { index: Box, }, - Identifier(String), + Conditional { + left: Box, + truthy: Box, + falsy: Box, + }, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] diff --git a/jexl-parser/src/parser.lalrpop b/jexl-parser/src/parser.lalrpop index f8d6ee6..670bb9c 100644 --- a/jexl-parser/src/parser.lalrpop +++ b/jexl-parser/src/parser.lalrpop @@ -32,10 +32,16 @@ Expr40: Box = { }; Expr50: Box = { - "|" => Box::new(Expression::Transform{name, subject, args}), - Expr60 + "?" ":" => Box::new(Expression::Conditional {left, truthy, falsy}), + Expr60, +} + +Expr60: Box = { + "|" => Box::new(Expression::Transform{name, subject, args}), + Expr70 }; + /// Expression for dereferencing. /// Used for dereferencing object literals, array literals, and the context /// There are two types of operations here: @@ -58,13 +64,13 @@ Expr50: Box = { /// `foo.bar[0] == {"baz": 1}` /// `foo.bar[1].bobo[0] == 13` /// `[1, 2, 3][1] == 2` -Expr60: Box = { - => Box::new(Expression::IndexOperation{subject, index}), - "." => Box::new(Expression::DotOperation{subject, ident}), - Expr70 +Expr70: Box = { + => Box::new(Expression::IndexOperation{subject, index}), + "." => Box::new(Expression::DotOperation{subject, ident}), + Expr80 }; -Expr70: Box = { +Expr80: Box = { Number => Box::new(Expression::Number(<>)), Boolean => Box::new(Expression::Boolean(<>)), String => Box::new(Expression::String(<>)),