use crate::ops::AsProxy;
use crate::ops::PartialOrd;
use rbs::Value;
use std::cmp::{Ordering, PartialOrd as P};
#[inline]
fn cmp_u64(value: u64, rhs: u64) -> Option<Ordering> {
Some(value.cmp(&rhs))
}
#[inline]
fn cmp_i64(value: i64, rhs: i64) -> Option<Ordering> {
Some(value.cmp(&rhs))
}
#[inline]
fn cmp_f64(value: f64, rhs: f64) -> Option<Ordering> {
value.partial_cmp(&rhs)
}
#[inline]
fn cmp_bool(value: bool, rhs: bool) -> Option<Ordering> {
Some(value.cmp(&rhs))
}
fn eq_u64(value: &Value, rhs: u64) -> Option<Ordering> {
let value = value.u64();
if value == rhs {
Some(Ordering::Equal)
} else if value > rhs {
Some(Ordering::Greater)
} else {
Some(Ordering::Less)
}
}
fn eq_i64(value: &Value, rhs: i64) -> Option<Ordering> {
let value = value.i64();
if value == rhs {
Some(Ordering::Equal)
} else if value > rhs {
Some(Ordering::Greater)
} else {
Some(Ordering::Less)
}
}
fn eq_f64(value: &Value, rhs: f64) -> Option<Ordering> {
let value = value.f64();
if value == rhs {
Some(Ordering::Equal)
} else if value > rhs {
Some(Ordering::Greater)
} else {
Some(Ordering::Less)
}
}
fn eq_bool(value: &Value, rhs: bool) -> Option<Ordering> {
let value = value.bool();
if value == rhs {
Some(Ordering::Equal)
} else if value == true && rhs == false {
Some(Ordering::Greater)
} else {
Some(Ordering::Less)
}
}
fn eq_str(value: &Value, rhs: &str) -> Option<Ordering> {
let value = value.clone().string();
if value == rhs {
Some(Ordering::Equal)
} else if value.as_str() > rhs {
Some(Ordering::Greater)
} else {
Some(Ordering::Less)
}
}
fn op_partial_cmp_value(left: &Value, rhs: &Value) -> Option<Ordering> {
match left {
Value::Null => Some(Ordering::Equal),
Value::Bool(b) => cmp_bool(*b, rhs.bool()),
Value::I32(n) => cmp_f64(*n as f64, rhs.f64()),
Value::I64(n) => cmp_f64(*n as f64, rhs.f64()),
Value::U32(n) => cmp_u64(*n as u64, rhs.u64()),
Value::U64(n) => cmp_u64(*n as u64, rhs.u64()),
Value::F32(n) => cmp_f64(*n as f64, rhs.f64()),
Value::F64(n) => cmp_f64(*n, rhs.f64()),
Value::String(s) => Some(s.as_str().cmp(&rhs.clone().string())),
Value::Ext(_, e) => op_partial_cmp_value(e.as_ref(), rhs),
_ => None,
}
}
impl PartialOrd<&Value> for &Value {
fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
op_partial_cmp_value(self, rhs)
}
}
impl PartialOrd<Value> for Value {
fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
op_partial_cmp_value(self, rhs)
}
}
impl PartialOrd<Value> for &Value {
fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
op_partial_cmp_value(self, rhs)
}
}
impl PartialOrd<&&Value> for &Value {
fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
op_partial_cmp_value(self, rhs)
}
}
impl PartialOrd<&Value> for Value {
fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
op_partial_cmp_value(self, rhs)
}
}
impl PartialOrd<&&Value> for Value {
fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
op_partial_cmp_value(self, rhs)
}
}
macro_rules! impl_numeric_cmp {
($($eq:ident [$($ty:ty)*])*) => {
$($(
impl PartialOrd<$ty> for Value {
fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
$eq(self, *rhs as _)
}
}
impl PartialOrd<&$ty> for Value {
fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
$eq(self, **rhs as _)
}
}
impl<'a> PartialOrd<$ty> for &'a Value {
fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
$eq(*self, *rhs as _)
}
}
impl<'a> PartialOrd<&$ty> for &'a Value {
fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
$eq(*self, **rhs as _)
}
}
impl PartialOrd<Value> for $ty {
fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
$eq(rhs, *self as _)
}
}
impl PartialOrd<&Value> for $ty {
fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
$eq(*rhs, *self as _)
}
}
impl PartialOrd<&&Value> for $ty {
fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
$eq(*rhs, *self as _)
}
}
)*)*
}
}
impl_numeric_cmp! {
eq_u64[u8 u16 u32 u64]
eq_i64[i8 i16 i32 i64 isize]
eq_f64[f32 f64]
eq_bool[bool]
eq_str[&str]
}
macro_rules! cmp_self {
($eq:ident[$($ty:ty)*]) => {
$(
impl PartialOrd<$ty> for $ty{
fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
$eq(*self as _, *rhs as _)
}
}
impl PartialOrd<&$ty> for $ty{
fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
$eq(*self as _, **rhs as _)
}
}
impl PartialOrd<$ty> for &$ty{
fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
$eq(**self as _, *rhs as _)
}
}
impl PartialOrd<&$ty> for &$ty{
fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
$eq(**self as _, **rhs as _)
}
}
)*
};
}
cmp_self!(cmp_u64[u8 u16 u32 u64]);
cmp_self!(cmp_i64[i8 i16 i32 i64 isize]);
cmp_self!(cmp_f64[f32 f64]);
impl PartialOrd<&str> for &str {
fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
self.partial_cmp(rhs)
}
}
impl PartialOrd<&str> for String {
fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
self.as_str().partial_cmp(rhs)
}
}
impl PartialOrd<String> for String {
fn op_partial_cmp(&self, rhs: &String) -> Option<Ordering> {
self.as_str().partial_cmp(rhs.as_str())
}
}
impl PartialOrd<&str> for &String {
fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
self.as_str().partial_cmp(rhs)
}
}
impl PartialOrd<String> for &String {
fn op_partial_cmp(&self, rhs: &String) -> Option<Ordering> {
self.as_str().partial_cmp(rhs.as_str())
}
}