1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Ruby numbers.

use std::cmp::Ordering;
use crate::{
    prelude::*,
    ruby,
};

mod float;
mod integer;

pub use self::{
    float::*,
    integer::*,
};

impl PartialEq<Integer> for Float {
    #[inline]
    fn eq(&self, other: &Integer) -> bool {
        other == self
    }
}

impl PartialOrd<Integer> for Float {
    #[inline]
    fn partial_cmp(&self, other: &Integer) -> Option<Ordering> {
        Some(other.partial_cmp(self)?.reverse())
    }
}

impl PartialOrd<Float> for Integer {
    #[inline]
    fn partial_cmp(&self, other: &Float) -> Option<Ordering> {
        let val = unsafe { ruby::rb_big_cmp(self.raw(), other.raw()) };
        if val != crate::util::NIL_VALUE {
            Some(crate::util::value_to_fixnum(val).cmp(&0))
        } else {
            None
        }
    }
}

macro_rules! forward_int_cmp {
    ($($t:ty)+) => { $(
        impl PartialEq<$t> for AnyObject {
            #[inline]
            fn eq(&self, other: &$t) -> bool {
                if let Some(integer) = self.to_integer() {
                    integer == *other
                } else if let Some(float) = self.to_float() {
                    float == Integer::from(*other)
                } else {
                    false
                }
            }
        }

        impl PartialEq<AnyObject> for $t {
            #[inline]
            fn eq(&self, other: &AnyObject) -> bool {
                other == self
            }
        }

        impl PartialOrd<$t> for AnyObject {
            #[inline]
            fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
                if let Some(integer) = self.to_integer() {
                    integer.partial_cmp(other)
                } else if let Some(float) = self.to_float() {
                    float.partial_cmp(&Integer::from(*other))
                } else {
                    None
                }
            }
        }

        impl PartialOrd<AnyObject> for $t {
            #[inline]
            fn partial_cmp(&self, other: &AnyObject) -> Option<Ordering> {
                Some(other.partial_cmp(self)?.reverse())
            }
        }
    )+ }
}

forward_int_cmp! {
    usize u128 u64 u32 u16 u8
    isize i128 i64 i32 i16 i8
}