en/
min.rs

1use std::cmp::Ordering;
2
3pub trait Min: PartialOrd {
4    fn min(self, other: Self) -> Self;
5}
6
7impl<T> Min for T
8where
9    T: PartialOrd,
10{
11    fn min(self, other: Self) -> Self {
12        match self.partial_cmp(&other) {
13            Some(Ordering::Less) | Some(Ordering::Equal) => self,
14            Some(Ordering::Greater) => other,
15            None => {
16                if self != self {
17                    other
18                } else {
19                    self
20                }
21            }
22        }
23    }
24}
25
26#[cfg(test)]
27mod test {
28    use super::Min;
29
30    #[test]
31    fn it_works() {
32        let three = 3i32;
33        let four = 4i32;
34        assert_eq!(Min::min(three, four), 3);
35        assert_eq!(Min::min(four, three), 3);
36        assert_eq!(Min::min(three, three), 3);
37    }
38
39    #[test]
40    fn pointer_identity() {
41        let three = std::rc::Rc::new(3);
42        let three_again = std::rc::Rc::new(3);
43        assert_eq!(*Min::min(&*three, &*three_again), 3);
44        assert!(std::ptr::eq(
45            Min::min(&*three, &*three_again),
46            std::cmp::Ord::min(&*three, &*three_again)
47        ));
48        assert!(std::ptr::eq(
49            Min::min(&*three_again, &*three),
50            std::cmp::Ord::min(&*three_again, &*three)
51        ));
52    }
53
54    #[test]
55    fn f32() {
56        let three = 3.0f32;
57        let four = 4.0;
58        assert_eq!(Min::min(three, four), f32::min(three, four));
59        assert_eq!(Min::min(four, three), f32::min(four, three));
60        assert_eq!(Min::min(three, three), f32::min(three, three));
61
62        let nan = std::f32::NAN;
63        assert_ne!(nan, nan); // we rely on this
64        assert_eq!(Min::min(three, nan), f32::min(three, nan));
65        assert_eq!(Min::min(nan, three), f32::min(nan, three));
66        assert_eq!(Min::min(nan, nan).is_nan(), f32::min(nan, nan).is_nan());
67
68        let inf = std::f32::INFINITY;
69        assert_eq!(Min::min(three, inf), f32::min(three, inf));
70        assert_eq!(Min::min(inf, three), f32::min(inf, three));
71
72        let neg_inf = std::f32::NEG_INFINITY;
73        assert_eq!(Min::min(three, neg_inf), f32::min(three, neg_inf));
74        assert_eq!(Min::min(neg_inf, three), f32::min(neg_inf, three));
75    }
76}