valitron 0.5.6

Valitron is an ergonomics, functional and configurable validator
Documentation
use std::cmp::Ordering;

use super::{
    float::{Float32, Float64},
    Value,
};

macro_rules! primitive_eq {
    ($($val:ident($ty:ty)),+) => {
        $(
            impl PartialEq<Value> for $ty {
                fn eq(&self, other: &Value) -> bool {
                    if let Value::$val(n) = other {
                        self == n
                    } else {
                        unreachable!("type mismatch")
                    }
                }
            }
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    if let Value::$val(n) = self {
                        n == other
                    } else {
                        unreachable!("type mismatch")
                    }
                }
            }

            impl PartialEq<&Value> for $ty {
                fn eq(&self, other: &&Value) -> bool {
                    if let Value::$val(n) = other {
                        self == n
                    } else {
                        unreachable!("type mismatch")
                    }
                }
            }
            impl PartialEq<$ty> for &Value {
                fn eq(&self, other: &$ty) -> bool {
                    if let Value::$val(n) = self {
                        n == other
                    } else {
                        unreachable!("type mismatch")
                    }
                }
            }

            impl PartialEq<&mut Value> for $ty {
                fn eq(&self, other: &&mut Value) -> bool {
                    if let Value::$val(n) = other {
                        self == n
                    } else {
                        unreachable!("type mismatch")
                    }
                }
            }
            impl PartialEq<$ty> for &mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    if let Value::$val(n) = self {
                        n == other
                    } else {
                        unreachable!("type mismatch")
                    }
                }
            }
        )+
    };
}

macro_rules! primitive_ord {
    ($($val:ident($ty:ty)),+) => {
        $(
            impl PartialOrd<Value> for $ty {
                fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
                    if let Value::$val(n) = other {
                        self.partial_cmp(n)
                    } else {
                        None
                    }
                }
            }
            impl PartialOrd<$ty> for Value {
                fn partial_cmp(&self, other: &$ty) -> Option<Ordering> {
                    if let Value::$val(n) = self {
                        n.partial_cmp(other)
                    } else {
                        None
                    }
                }
            }

            impl PartialOrd<&Value> for $ty {
                fn partial_cmp(&self, other: &&Value) -> Option<Ordering> {
                    if let Value::$val(n) = other {
                        self.partial_cmp(n)
                    } else {
                        None
                    }
                }
            }
            impl PartialOrd<$ty> for &Value {
                fn partial_cmp(&self, other: &$ty) -> Option<Ordering> {
                    if let Value::$val(n) = self {
                        n.partial_cmp(other)
                    } else {
                        None
                    }
                }
            }

            impl PartialOrd<&mut Value> for $ty {
                fn partial_cmp(&self, other: &&mut Value) -> Option<Ordering> {
                    if let Value::$val(n) = other {
                        self.partial_cmp(n)
                    } else {
                        None
                    }
                }
            }
            impl PartialOrd<$ty> for &mut Value {
                fn partial_cmp(&self, other: &$ty) -> Option<Ordering> {
                    if let Value::$val(n) = self {
                        n.partial_cmp(other)
                    } else {
                        None
                    }
                }
            }
        )+
    };
}

primitive_eq!(
    Uint8(u8),
    Int8(i8),
    Uint16(u16),
    Int16(i16),
    Uint32(u32),
    Int32(i32),
    Uint64(u64),
    Int64(i64),
    String(String),
    Boolean(bool),
    Char(char)
);

primitive_ord!(
    Uint8(u8),
    Int8(i8),
    Uint16(u16),
    Int16(i16),
    Uint32(u32),
    Int32(i32),
    Uint64(u64),
    Int64(i64),
    String(String),
    Boolean(bool),
    Char(char)
);

impl PartialEq<Value> for f32 {
    fn eq(&self, other: &Value) -> bool {
        if let Value::Float32(Float32(f)) = other {
            if self.is_finite() && f.is_finite() {
                self == f
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<f32> for Value {
    fn eq(&self, other: &f32) -> bool {
        if let Value::Float32(Float32(f)) = self {
            if f.is_finite() && other.is_finite() {
                f == other
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<&Value> for f32 {
    fn eq(&self, other: &&Value) -> bool {
        if let Value::Float32(Float32(f)) = other {
            if self.is_finite() && f.is_finite() {
                self == f
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<f32> for &Value {
    fn eq(&self, other: &f32) -> bool {
        if let Value::Float32(Float32(f)) = self {
            if f.is_finite() && other.is_finite() {
                f == other
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}
impl PartialEq<&mut Value> for f32 {
    fn eq(&self, other: &&mut Value) -> bool {
        if let Value::Float32(Float32(f)) = other {
            if self.is_finite() && f.is_finite() {
                self == f
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<f32> for &mut Value {
    fn eq(&self, other: &f32) -> bool {
        if let Value::Float32(Float32(f)) = self {
            if f.is_finite() && other.is_finite() {
                f == other
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<Value> for f64 {
    fn eq(&self, other: &Value) -> bool {
        if let Value::Float64(Float64(f)) = other {
            if self.is_finite() && f.is_finite() {
                self == f
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<f64> for Value {
    fn eq(&self, other: &f64) -> bool {
        if let Value::Float64(Float64(f)) = self {
            if f.is_finite() && other.is_finite() {
                f == other
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<&Value> for f64 {
    fn eq(&self, other: &&Value) -> bool {
        if let Value::Float64(Float64(f)) = other {
            if self.is_finite() && f.is_finite() {
                self == f
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<f64> for &Value {
    fn eq(&self, other: &f64) -> bool {
        if let Value::Float64(Float64(f)) = self {
            if f.is_finite() && other.is_finite() {
                f == other
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<&mut Value> for f64 {
    fn eq(&self, other: &&mut Value) -> bool {
        if let Value::Float64(Float64(f)) = other {
            if self.is_finite() && f.is_finite() {
                self == f
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

impl PartialEq<f64> for &mut Value {
    fn eq(&self, other: &f64) -> bool {
        if let Value::Float64(Float64(f)) = self {
            if f.is_finite() && other.is_finite() {
                f == other
            } else {
                false
            }
        } else {
            unreachable!("type mismatch")
        }
    }
}

#[test]
fn all() {
    let mut value = Value::Uint8(10);

    assert!(value == 10_u8);
    assert!(value > 9_u8);
    assert!(&value == 10_u8);
    assert!(&value > 9_u8);
    assert!(&mut value == 10_u8);
    assert!(&mut value > 9_u8);

    let value = Value::Float32(Float32(1.1));
    let f = 1.1_f32;
    assert!(value == f);

    let value_nan = Value::Float32(Float32(f32::NAN));
    let f_nan = f32::NAN;
    assert!(value_nan != f_nan);
}

#[test]
#[should_panic]
fn type_mismatch() {
    let value = Value::Uint8(10);
    assert!(value == 10_i8);
}