ranges/domain/
u32.rs

1use core::{cmp::Ordering, ops::Bound};
2
3use super::{Domain, Iterable};
4
5impl Domain for u32 {
6    const DISCRETE: bool = true;
7
8    /// Always returns `Some(self - 1)` unless `self` is zero.
9    #[must_use]
10    #[allow(clippy::arithmetic_side_effects)]
11    fn predecessor(&self) -> Option<Self> {
12        match *self {
13            Self::MIN => None,
14            _ => Some(self - 1),
15        }
16    }
17
18    /// Always returns `Some(self + 1)` unless `self` is `Self::MAX`.
19    #[must_use]
20    #[allow(clippy::arithmetic_side_effects)]
21    fn successor(&self) -> Option<Self> {
22        match *self {
23            Self::MAX => None,
24            _ => Some(self + 1),
25        }
26    }
27
28    /// Returns `Included(Self::MIN)`.
29    #[must_use]
30    fn minimum() -> Bound<Self> {
31        Bound::Included(Self::MIN)
32    }
33
34    /// Returns `Included(Self::MAX)`.
35    #[must_use]
36    fn maximum() -> Bound<Self> {
37        Bound::Included(Self::MAX)
38    }
39
40    #[must_use]
41    #[allow(clippy::shadow_reuse, clippy::arithmetic_side_effects)]
42    fn shares_neighbour_with(&self, other: &Self) -> bool {
43        let (big, small) = match self.cmp(other) {
44            Ordering::Less => (other, self),
45            Ordering::Equal => return false,
46            Ordering::Greater => (self, other),
47        };
48
49        big - small == 2
50    }
51}
52
53impl Iterable for u32 {
54    type Output = Self;
55
56    fn next(&self) -> Option<Self::Output> {
57        if *self == Self::MAX {
58            None
59        } else {
60            #[allow(clippy::arithmetic_side_effects)]
61            Some(*self + 1)
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use crate::Domain;
69
70    #[test]
71    fn is_next_to() {
72        assert!(u32::MIN.is_next_to(&(u32::MIN + 1)));
73        assert!((u32::MIN + 1).is_next_to(&u32::MIN));
74        assert!(!u32::MIN.is_next_to(&(u32::MIN + 2)));
75        assert!(!u32::MIN.is_next_to(&u32::MAX));
76        assert!(!u32::MAX.is_next_to(&u32::MIN));
77    }
78
79    #[test]
80    fn shares_neighbour_with() {
81        // self-distance
82        assert!(!u32::MIN.shares_neighbour_with(&u32::MIN));
83
84        // "normal" value
85        assert!(!42_u32.shares_neighbour_with(&45));
86        assert!(!45_u32.shares_neighbour_with(&42));
87
88        assert!(42_u32.shares_neighbour_with(&44));
89        assert!(44_u32.shares_neighbour_with(&42));
90
91        // boundary check
92        assert!(!u32::MIN.shares_neighbour_with(&u32::MAX));
93        assert!(!u32::MAX.shares_neighbour_with(&u32::MIN));
94    }
95}