1use core::{cmp::Ordering, ops::Bound};
2
3use super::{Domain, Iterable};
4
5impl Domain for u32 {
6 const DISCRETE: bool = true;
7
8 #[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 #[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 #[must_use]
30 fn minimum() -> Bound<Self> {
31 Bound::Included(Self::MIN)
32 }
33
34 #[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 assert!(!u32::MIN.shares_neighbour_with(&u32::MIN));
83
84 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 assert!(!u32::MIN.shares_neighbour_with(&u32::MAX));
93 assert!(!u32::MAX.shares_neighbour_with(&u32::MIN));
94 }
95}