Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 63 additions & 38 deletions engine/src/ast/index_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ pub struct IndexExpr {
pub indexes: Vec<FieldIndex>,
}

#[allow(clippy::manual_ok_err)]
#[inline]
pub fn ok_ref<T, E>(result: &Result<T, E>) -> 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) {
Expand All @@ -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 {
Expand All @@ -86,20 +77,20 @@ 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) => {
let call = compiler.compile_function_call_expr(call);
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)
})
}
Expand Down Expand Up @@ -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),
)
})
}
Expand All @@ -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),
)
})
}
Expand All @@ -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 = &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 = &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 = &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 = &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 = &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 = &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)),
)
},
)
},
)
}),
})
}
}
}
}

Expand Down
35 changes: 0 additions & 35 deletions engine/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<&'a LhsValue<'a>>, 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,
Expand Down