1use std::num::{
2 NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU16, NonZeroU32,
3 NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
4};
5
6use crate::Int;
7
8pub trait IntKey: Copy {
40 type Int: Int;
42
43 const PRIME: Self::Int;
47
48 fn into_int(self) -> Self::Int;
55}
56
57macro_rules! impl_int_key_for_int {
58 ($self:ident, $prime:expr) => {
59 impl IntKey for $self {
60 type Int = $self;
61
62 const PRIME: Self::Int = $prime;
63
64 fn into_int(self) -> Self::Int {
65 self
66 }
67 }
68 };
69}
70
71const U8_PRIME_MAX: u8 = u8::MAX - 4; const U16_PRIME_MAX: u16 = u16::MAX - 14; const U32_PRIME_MAX: u32 = u32::MAX - 4; const U64_PRIME_MAX: u64 = u64::MAX - 58; const U128_PRIME_MAX: u128 = u128::MAX - 158; impl_int_key_for_int!(u8, U8_PRIME_MAX);
80impl_int_key_for_int!(u16, U16_PRIME_MAX);
81impl_int_key_for_int!(u32, U32_PRIME_MAX);
82impl_int_key_for_int!(u64, U64_PRIME_MAX);
83impl_int_key_for_int!(u128, U128_PRIME_MAX);
84#[cfg(target_pointer_width = "16")]
85impl_int_key_for_int!(usize, U16_PRIME_MAX as usize);
86#[cfg(target_pointer_width = "32")]
87impl_int_key_for_int!(usize, U32_PRIME_MAX as usize);
88#[cfg(target_pointer_width = "64")]
89impl_int_key_for_int!(usize, U64_PRIME_MAX as usize);
90
91macro_rules! impl_int_key_for_signed_int {
92 ($self:ident, $unsigned:ident) => {
93 impl IntKey for $self {
94 type Int = $unsigned;
95
96 const PRIME: Self::Int = $unsigned::PRIME;
97
98 fn into_int(self) -> Self::Int {
99 self as $unsigned
100 }
101 }
102 };
103}
104
105impl_int_key_for_signed_int!(i8, u8);
106impl_int_key_for_signed_int!(i16, u16);
107impl_int_key_for_signed_int!(i32, u32);
108impl_int_key_for_signed_int!(i64, u64);
109impl_int_key_for_signed_int!(i128, u128);
110impl_int_key_for_signed_int!(isize, usize);
111
112macro_rules! impl_int_key_for_non_zero_int {
113 ($non_zero_int:ident, $int:ident) => {
114 impl IntKey for $non_zero_int {
115 type Int = <$int as IntKey>::Int;
116
117 const PRIME: Self::Int = $int::PRIME;
118
119 fn into_int(self) -> Self::Int {
120 self.get().into_int()
121 }
122 }
123 };
124}
125
126impl_int_key_for_non_zero_int!(NonZeroU8, u8);
127impl_int_key_for_non_zero_int!(NonZeroU16, u16);
128impl_int_key_for_non_zero_int!(NonZeroU32, u32);
129impl_int_key_for_non_zero_int!(NonZeroU64, u64);
130impl_int_key_for_non_zero_int!(NonZeroUsize, usize);
131impl_int_key_for_non_zero_int!(NonZeroI8, i8);
132impl_int_key_for_non_zero_int!(NonZeroI16, i16);
133impl_int_key_for_non_zero_int!(NonZeroI32, i32);
134impl_int_key_for_non_zero_int!(NonZeroI64, i64);
135impl_int_key_for_non_zero_int!(NonZeroIsize, isize);
136
137impl<K: IntKey> IntKey for Wrapping<K> {
138 type Int = K::Int;
139
140 const PRIME: Self::Int = K::PRIME;
141
142 fn into_int(self) -> Self::Int {
143 self.0.into_int()
144 }
145}
146
147impl IntKey for std::net::Ipv4Addr {
148 type Int = u32;
149
150 const PRIME: Self::Int = u32::PRIME;
151
152 fn into_int(self) -> Self::Int {
153 u32::from_be_bytes(self.octets())
155 }
156}
157
158impl IntKey for std::net::Ipv6Addr {
159 type Int = u128;
160
161 const PRIME: Self::Int = u128::PRIME;
162
163 fn into_int(self) -> Self::Int {
164 u128::from_be_bytes(self.octets())
166 }
167}