Skip to content

Commit a8b0544

Browse files
Masterlvngraftzhang
and
raftzhang
authored
feat: Implement Short-Circuit Evaluation for AND Expressions to Fix Issue #117 (#118)
* feat: Implement short-circuit evaluation for AND expression * format code for objects.rs * format objects.rs code * fix and Expression * fix code linter issue --------- Co-authored-by: raftzhang <[email protected]>
1 parent 4effd74 commit a8b0544

File tree

5 files changed

+30
-12
lines changed

5 files changed

+30
-12
lines changed

interpreter/src/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub enum Context<'a> {
4040
},
4141
}
4242

43-
impl<'a> Context<'a> {
43+
impl Context<'_> {
4444
pub fn add_variable<S, V>(
4545
&mut self,
4646
name: S,
@@ -159,7 +159,7 @@ impl<'a> Context<'a> {
159159
}
160160
}
161161

162-
impl<'a> Default for Context<'a> {
162+
impl Default for Context<'_> {
163163
fn default() -> Self {
164164
let mut ctx = Context::Root {
165165
variables: Default::default(),

interpreter/src/functions.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ pub fn all(
381381
ident: Identifier,
382382
expr: Expression,
383383
) -> Result<bool> {
384-
return match this {
384+
match this {
385385
Value::List(items) => {
386386
let mut ptx = ftx.ptx.new_inner_scope();
387387
for item in items.iter() {
@@ -402,8 +402,8 @@ pub fn all(
402402
}
403403
Ok(true)
404404
}
405-
_ => return Err(this.error_expected_type(ValueType::List)),
406-
};
405+
_ => Err(this.error_expected_type(ValueType::List)),
406+
}
407407
}
408408

409409
/// Returns a boolean value indicating whether a or more values in the provided

interpreter/src/magic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl From<Identifier> for String {
230230
#[derive(Clone)]
231231
pub struct Arguments(pub Arc<Vec<Value>>);
232232

233-
impl<'a, 'context> FromContext<'a, 'context> for Arguments {
233+
impl<'a> FromContext<'a, '_> for Arguments {
234234
fn from_context(ctx: &'a mut FunctionContext) -> Result<Self, ExecutionError>
235235
where
236236
Self: Sized,
@@ -389,7 +389,7 @@ impl<'a, 'context, H, T> HandlerCallable<'a, 'context, H, T> {
389389
}
390390
}
391391

392-
impl<'a, 'context, H, T> Callable for HandlerCallable<'a, 'context, H, T>
392+
impl<H, T> Callable for HandlerCallable<'_, '_, H, T>
393393
where
394394
H: Handler<T> + Clone + 'static,
395395
{

interpreter/src/objects.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ impl From<Value> for ResolveResult {
405405
}
406406
}
407407

408-
impl<'a> Value {
408+
impl Value {
409409
pub fn resolve_all(expr: &[Expression], ctx: &Context) -> ResolveResult {
410410
let mut res = Vec::with_capacity(expr.len());
411411
for expr in expr {
@@ -415,7 +415,7 @@ impl<'a> Value {
415415
}
416416

417417
#[inline(always)]
418-
pub fn resolve(expr: &'a Expression, ctx: &Context) -> ResolveResult {
418+
pub fn resolve(expr: &Expression, ctx: &Context) -> ResolveResult {
419419
match expr {
420420
Expression::Atom(atom) => Ok(atom.into()),
421421
Expression::Arithmetic(left, op, right) => {
@@ -486,8 +486,12 @@ impl<'a> Value {
486486
}
487487
Expression::And(left, right) => {
488488
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+
}
491495
}
492496
Expression::Unary(op, expr) => {
493497
let expr = Value::resolve(expr, ctx)?;
@@ -973,4 +977,18 @@ mod tests {
973977
)))]))
974978
);
975979
}
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+
}
976994
}

parser/src/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub struct ExpressionReferences<'expr> {
7373
functions: HashSet<&'expr str>,
7474
}
7575

76-
impl<'expr> ExpressionReferences<'expr> {
76+
impl ExpressionReferences<'_> {
7777
/// Returns true if the expression references the provided variable name.
7878
///
7979
/// # Example

0 commit comments

Comments
 (0)