use crate::value::{Value, compare, ops::numeric, semantics};
use std::cmp::Ordering;
#[must_use]
pub fn canonical_cmp_map_entry(
left_key: &Value,
left_value: &Value,
right_key: &Value,
right_value: &Value,
) -> Ordering {
Value::canonical_cmp_key(left_key, right_key)
.then_with(|| Value::canonical_cmp(left_value, right_value))
}
#[must_use]
pub fn ordered_map_entries(entries: &[(Value, Value)]) -> Vec<&(Value, Value)> {
let mut ordered = entries.iter().collect::<Vec<_>>();
ordered.sort_by(|left, right| canonical_cmp_map_entry(&left.0, &left.1, &right.0, &right.1));
ordered
}
#[must_use]
pub(crate) fn strict_order_cmp(left: &Value, right: &Value) -> Option<Ordering> {
compare::strict_order_cmp(left, right)
}
#[must_use]
pub(crate) fn eq(left: &Value, right: &Value) -> Option<bool> {
let numeric_widen_enabled =
semantics::supports_numeric_coercion(left) || semantics::supports_numeric_coercion(right);
if numeric_widen_enabled {
return numeric::compare_decimal_order(left, right)
.map(|ordering| ordering == Ordering::Equal);
}
Some(left == right)
}
#[must_use]
pub(crate) fn ne(left: &Value, right: &Value) -> Option<bool> {
eq(left, right).map(|equal| !equal)
}
#[must_use]
pub(crate) fn order(left: &Value, right: &Value) -> Option<Ordering> {
let numeric_widen_enabled =
semantics::supports_numeric_coercion(left) || semantics::supports_numeric_coercion(right);
if numeric_widen_enabled {
return numeric::compare_decimal_order(left, right);
}
strict_order_cmp(left, right)
}
#[must_use]
pub(crate) fn lt(left: &Value, right: &Value) -> Option<bool> {
order(left, right).map(Ordering::is_lt)
}
#[must_use]
pub(crate) fn lte(left: &Value, right: &Value) -> Option<bool> {
order(left, right).map(Ordering::is_le)
}
#[must_use]
pub(crate) fn gt(left: &Value, right: &Value) -> Option<bool> {
order(left, right).map(Ordering::is_gt)
}
#[must_use]
pub(crate) fn gte(left: &Value, right: &Value) -> Option<bool> {
order(left, right).map(Ordering::is_ge)
}
impl Value {
#[must_use]
pub(crate) fn canonical_cmp_map_entry(
left_key: &Self,
left_value: &Self,
right_key: &Self,
right_value: &Self,
) -> Ordering {
canonical_cmp_map_entry(left_key, left_value, right_key, right_value)
}
#[must_use]
pub(crate) fn ordered_map_entries(entries: &[(Self, Self)]) -> Vec<&(Self, Self)> {
ordered_map_entries(entries)
}
#[must_use]
pub(crate) fn strict_order_cmp(left: &Self, right: &Self) -> Option<Ordering> {
strict_order_cmp(left, right)
}
}