use crate::{
db::predicate::{CoercionId, CompareOp, ComparePredicate},
value::{Value, canonicalize_value_set},
};
pub(in crate::db) struct MembershipCompareLeaf<'a> {
field: &'a str,
value: Value,
coercion: CoercionId,
}
impl<'a> MembershipCompareLeaf<'a> {
#[must_use]
pub(in crate::db) const fn new(field: &'a str, value: Value, coercion: CoercionId) -> Self {
Self {
field,
value,
coercion,
}
}
}
pub(in crate::db) fn collapse_membership_compare_leaves<'a>(
leaves: impl IntoIterator<Item = MembershipCompareLeaf<'a>>,
target_op: CompareOp,
) -> Option<ComparePredicate> {
let mut field = None;
let mut coercion = None;
let mut values = Vec::new();
for leaf in leaves {
if let Some(current) = field {
if current != leaf.field {
return None;
}
} else {
field = Some(leaf.field);
}
if let Some(current) = coercion {
if current != leaf.coercion {
return None;
}
} else {
coercion = Some(leaf.coercion);
}
values.push(leaf.value);
}
if values.len() < 2 {
return None;
}
canonicalize_value_set(&mut values);
Some(ComparePredicate::with_coercion(
field?,
target_op,
Value::List(values),
coercion?,
))
}