diff --git a/engine/src/ast/index_expr.rs b/engine/src/ast/index_expr.rs index dd1116cd..fa54271b 100644 --- a/engine/src/ast/index_expr.rs +++ b/engine/src/ast/index_expr.rs @@ -31,15 +31,6 @@ pub struct IndexExpr { pub indexes: Vec, } -#[allow(clippy::manual_ok_err)] -#[inline] -pub fn ok_ref(result: &Result) -> Option<&T> { - match result { - Ok(x) => Some(x), - Err(_) => None, - } -} - impl ValueExpr for IndexExpr { #[inline] fn walk<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { @@ -64,7 +55,7 @@ impl ValueExpr for IndexExpr { let map_each_count = self.map_each_count(); let Self { identifier, - indexes, + mut indexes, } = self; let last = match map_each_count { @@ -86,12 +77,12 @@ impl ValueExpr for IndexExpr { IdentifierExpr::FunctionCallExpr(call) => compiler.compile_function_call_expr(call), } } else if let Some(last) = last { + indexes.truncate(last); // Average path match identifier { IdentifierExpr::Field(f) => CompiledValueExpr::new(move |ctx| { ctx.get_field_value_unchecked(&f) - .and_then(|value| value.get_nested(&indexes[..last])) - .map(LhsValue::as_ref) + .and_then(|value| value.as_ref().extract_nested(&indexes)) .ok_or(ty) }), IdentifierExpr::FunctionCallExpr(call) => { @@ -99,7 +90,7 @@ impl ValueExpr for IndexExpr { CompiledValueExpr::new(move |ctx| { call.execute(ctx) .ok() - .and_then(|val| val.extract_nested(&indexes[..last])) + .and_then(|val| val.extract_nested(&indexes)) .ok_or(ty) }) } @@ -168,12 +159,13 @@ impl IndexExpr { }) } else { CompiledOneExpr::new(move |ctx| { - ok_ref(&call.execute(ctx)) - .and_then(|val| val.get_nested(&indexes)) + call.execute(ctx) + .ok() + .and_then(|val| val.extract_nested(&indexes)) .map_or( default, #[inline] - |val| comp.compare(val, ctx), + |val| comp.compare(&val, ctx), ) }) } @@ -188,11 +180,11 @@ impl IndexExpr { } else { CompiledOneExpr::new(move |ctx| { ctx.get_field_value_unchecked(&f) - .and_then(|value| value.get_nested(&indexes)) + .and_then(|value| value.as_ref().extract_nested(&indexes)) .map_or( default, #[inline] - |val| comp.compare(val, ctx), + |val| comp.compare(&val, ctx), ) }) } @@ -213,35 +205,68 @@ impl IndexExpr { match identifier { IdentifierExpr::FunctionCallExpr(call) => { let call = compiler.compile_function_call_expr(call); - CompiledVecExpr::new(move |ctx| { - let comp = ∁ - ok_ref(&call.execute(ctx)) - .and_then(|val| val.get_nested(&indexes)) - .map_or( + if indexes.is_empty() { + CompiledVecExpr::new(move |ctx| { + let comp = ∁ + call.execute(ctx).map_or( BOOL_ARRAY, #[inline] - |val: &LhsValue<'_>| { + |val: LhsValue<'_>| { TypedArray::from_iter( val.iter().unwrap().map(|item| comp.compare(item, ctx)), ) }, ) - }) + }) + } else { + CompiledVecExpr::new(move |ctx| { + let comp = ∁ + call.execute(ctx) + .ok() + .and_then(|val| val.extract_nested(&indexes)) + .map_or( + BOOL_ARRAY, + #[inline] + |val: LhsValue<'_>| { + TypedArray::from_iter( + val.iter().unwrap().map(|item| comp.compare(item, ctx)), + ) + }, + ) + }) + } } - IdentifierExpr::Field(f) => CompiledVecExpr::new(move |ctx| { - let comp = ∁ - ctx.get_field_value_unchecked(&f) - .and_then(|value| value.get_nested(&indexes)) - .map_or( - BOOL_ARRAY, - #[inline] - |val: &LhsValue<'_>| { - TypedArray::from_iter( - val.iter().unwrap().map(|item| comp.compare(item, ctx)), + IdentifierExpr::Field(f) => { + if indexes.is_empty() { + CompiledVecExpr::new(move |ctx| { + let comp = ∁ + ctx.get_field_value_unchecked(&f).map_or( + BOOL_ARRAY, + #[inline] + |val: &LhsValue<'_>| { + TypedArray::from_iter( + val.iter().unwrap().map(|item| comp.compare(item, ctx)), + ) + }, + ) + }) + } else { + CompiledVecExpr::new(move |ctx| { + let comp = ∁ + ctx.get_field_value_unchecked(&f) + .and_then(|value| value.as_ref().extract_nested(&indexes)) + .map_or( + BOOL_ARRAY, + #[inline] + |val: LhsValue<'_>| { + TypedArray::from_iter( + val.iter().unwrap().map(|item| comp.compare(item, ctx)), + ) + }, ) - }, - ) - }), + }) + } + } } } diff --git a/engine/src/types.rs b/engine/src/types.rs index 997a2600..6b2c45e7 100644 --- a/engine/src/types.rs +++ b/engine/src/types.rs @@ -701,41 +701,6 @@ impl<'a> LhsValue<'a> { } } - /// Retrieve an element from an LhsValue given a path item and a specified - /// type. - /// Returns a TypeMismatchError error if current type does not support it - /// nested element. - /// - /// Both LhsValue::Array and LhsValue::Map support nested elements. - pub(crate) fn get( - &'a self, - item: &FieldIndex, - ) -> Result>, IndexAccessError> { - match (self, item) { - (LhsValue::Array(arr), FieldIndex::ArrayIndex(idx)) => Ok(arr.get(*idx as usize)), - (_, FieldIndex::ArrayIndex(_)) => Err(IndexAccessError { - index: item.clone(), - actual: self.get_type(), - }), - (LhsValue::Map(map), FieldIndex::MapKey(key)) => Ok(map.get(key.as_bytes())), - (_, FieldIndex::MapKey(_)) => Err(IndexAccessError { - index: item.clone(), - actual: self.get_type(), - }), - (_, FieldIndex::MapEach) => Err(IndexAccessError { - index: item.clone(), - actual: self.get_type(), - }), - } - } - - #[inline] - pub(crate) fn get_nested(&'a self, indexes: &[FieldIndex]) -> Option<&'a LhsValue<'a>> { - indexes - .iter() - .try_fold(self, |value, idx| value.get(idx).unwrap()) - } - pub(crate) fn extract( self, item: &FieldIndex,