From 2e8d65eb1d213e16ed95420f1991cc566b14fa2b Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Fri, 8 Nov 2024 15:37:39 +0000 Subject: [PATCH] Refactor unary filters to deduplicate logic. Same approach as #695, just over unary filters instead of binary ones. --- trustfall_core/src/interpreter/filtering.rs | 41 +++++++++++---------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/trustfall_core/src/interpreter/filtering.rs b/trustfall_core/src/interpreter/filtering.rs index 805eae81..61d15f2c 100644 --- a/trustfall_core/src/interpreter/filtering.rs +++ b/trustfall_core/src/interpreter/filtering.rs @@ -223,31 +223,32 @@ pub(super) fn regex_matches_optimized(left: &FieldValue, regex: &Regex) -> bool } } +fn apply_unary_filter< + 'query, + Vertex: Debug + Clone + 'query, + FilterFn: Fn(&FieldValue) -> bool + 'query, +>( + filter_op: FilterFn, + iterator: ContextIterator<'query, Vertex>, +) -> ContextIterator<'query, Vertex> { + Box::new(iterator.filter_map(move |mut context| { + let last_value = context.values.pop().expect("no value present"); + filter_op(&last_value).then_some(context) + })) +} + +#[inline(always)] +fn is_null(value: &FieldValue) -> bool { + matches!(value, FieldValue::Null) +} + fn attempt_apply_unary_filter<'query, Vertex: Debug + Clone + 'query>( filter: &Operation<(), &Argument>, iterator: ContextIterator<'query, Vertex>, ) -> Result, ContextIterator<'query, Vertex>> { match filter { - Operation::IsNull(_) => { - let output_iter = iterator.filter_map(move |mut context| { - let last_value = context.values.pop().expect("no value present"); - match last_value { - FieldValue::Null => Some(context), - _ => None, - } - }); - Ok(Box::new(output_iter)) - } - Operation::IsNotNull(_) => { - let output_iter = iterator.filter_map(move |mut context| { - let last_value = context.values.pop().expect("no value present"); - match last_value { - FieldValue::Null => None, - _ => Some(context), - } - }); - Ok(Box::new(output_iter)) - } + Operation::IsNull(_) => Ok(apply_unary_filter(is_null, iterator)), + Operation::IsNotNull(_) => Ok(apply_unary_filter(|v| !is_null(v), iterator)), _ => Err(iterator), } }