@@ -405,7 +405,7 @@ impl From<Value> for ResolveResult {
405
405
}
406
406
}
407
407
408
- impl < ' a > Value {
408
+ impl Value {
409
409
pub fn resolve_all ( expr : & [ Expression ] , ctx : & Context ) -> ResolveResult {
410
410
let mut res = Vec :: with_capacity ( expr. len ( ) ) ;
411
411
for expr in expr {
@@ -415,7 +415,7 @@ impl<'a> Value {
415
415
}
416
416
417
417
#[ inline( always) ]
418
- pub fn resolve ( expr : & ' a Expression , ctx : & Context ) -> ResolveResult {
418
+ pub fn resolve ( expr : & Expression , ctx : & Context ) -> ResolveResult {
419
419
match expr {
420
420
Expression :: Atom ( atom) => Ok ( atom. into ( ) ) ,
421
421
Expression :: Arithmetic ( left, op, right) => {
@@ -486,8 +486,12 @@ impl<'a> Value {
486
486
}
487
487
Expression :: And ( left, right) => {
488
488
let left = Value :: resolve ( left, ctx) ?;
489
- let right = Value :: resolve ( right, ctx) ?;
490
- Value :: Bool ( left. to_bool ( ) && right. to_bool ( ) ) . into ( )
489
+ if !left. to_bool ( ) {
490
+ Value :: Bool ( false ) . into ( )
491
+ } else {
492
+ let right = Value :: resolve ( right, ctx) ?;
493
+ Value :: Bool ( right. to_bool ( ) ) . into ( )
494
+ }
491
495
}
492
496
Expression :: Unary ( op, expr) => {
493
497
let expr = Value :: resolve ( expr, ctx) ?;
@@ -973,4 +977,18 @@ mod tests {
973
977
) ) ) ] ) )
974
978
) ;
975
979
}
980
+
981
+ #[ test]
982
+ fn test_short_curcuit_and ( ) {
983
+ let mut context = Context :: default ( ) ;
984
+ let data: HashMap < String , String > = HashMap :: new ( ) ;
985
+ context. add_variable_from_value ( "data" , data) ;
986
+
987
+ let program = Program :: compile ( "has(data.x) && data.x.startsWith(\" foo\" )" ) . unwrap ( ) ;
988
+ let value = program. execute ( & context) ;
989
+ assert ! (
990
+ value. is_ok( ) ,
991
+ "The AND expression should support short-circuit evaluation."
992
+ ) ;
993
+ }
976
994
}
0 commit comments