/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nonmax-0.5.5/src/lib.rs
Line | Count | Source |
1 | | /*! |
2 | | [](https://github.com/LPGhatguy/nonmax/actions) |
3 | | [](https://crates.io/crates/nonmax) |
4 | | [](https://docs.rs/nonmax) |
5 | | |
6 | | nonmax provides types similar to the std `NonZero*` types, but instead requires |
7 | | that their values are not the maximum for their type. This ensures that |
8 | | `Option<NonMax*>` is no larger than `NonMax*`. |
9 | | |
10 | | nonmax supports every type that has a corresponding non-zero variant in the |
11 | | standard library: |
12 | | |
13 | | * `NonMaxI8` |
14 | | * `NonMaxI16` |
15 | | * `NonMaxI32` |
16 | | * `NonMaxI64` |
17 | | * `NonMaxI128` |
18 | | * `NonMaxIsize` |
19 | | * `NonMaxU8` |
20 | | * `NonMaxU16` |
21 | | * `NonMaxU32` |
22 | | * `NonMaxU64` |
23 | | * `NonMaxU128` |
24 | | * `NonMaxUsize` |
25 | | |
26 | | ## Example |
27 | | |
28 | | ``` |
29 | | use nonmax::{NonMaxI16, NonMaxU8}; |
30 | | |
31 | | let value = NonMaxU8::new(16).expect("16 should definitely fit in a u8"); |
32 | | assert_eq!(value.get(), 16); |
33 | | assert_eq!(std::mem::size_of_val(&value), 1); |
34 | | |
35 | | let signed = NonMaxI16::new(i16::min_value()).expect("minimum values are fine"); |
36 | | assert_eq!(signed.get(), i16::min_value()); |
37 | | assert_eq!(std::mem::size_of_val(&signed), 2); |
38 | | |
39 | | let oops = NonMaxU8::new(255); |
40 | | assert_eq!(oops, None); |
41 | | ``` |
42 | | |
43 | | ## Features |
44 | | |
45 | | * `std` (default): implements [`std::error::Error`] for [`ParseIntError`] and |
46 | | [`TryFromIntError`]. Disable this feature for |
47 | | [`#![no_std]`](https://rust-embedded.github.io/book/intro/no-std.html) support. |
48 | | |
49 | | ## Minimum Supported Rust Version (MSRV) |
50 | | |
51 | | nonmax supports Rust 1.47.0 and newer. Until this library reaches 1.0, |
52 | | changes to the MSRV will require major version bumps. After 1.0, MSRV changes |
53 | | will only require minor version bumps, but will need significant justification. |
54 | | */ |
55 | | |
56 | | #![forbid(missing_docs)] |
57 | | #![cfg_attr(not(feature = "std"), no_std)] |
58 | | |
59 | | /// An error type returned when a checked integral type conversion fails (mimics [std::num::TryFromIntError]) |
60 | | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
61 | | pub struct TryFromIntError(()); |
62 | | |
63 | | #[cfg(feature = "std")] |
64 | | impl std::error::Error for TryFromIntError {} |
65 | | |
66 | | impl core::fmt::Display for TryFromIntError { |
67 | 0 | fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { |
68 | 0 | "out of range integral type conversion attempted".fmt(fmt) |
69 | 0 | } |
70 | | } |
71 | | |
72 | | impl From<core::num::TryFromIntError> for TryFromIntError { |
73 | 0 | fn from(_: core::num::TryFromIntError) -> Self { |
74 | 0 | Self(()) |
75 | 0 | } |
76 | | } |
77 | | |
78 | | impl From<core::convert::Infallible> for TryFromIntError { |
79 | | fn from(never: core::convert::Infallible) -> Self { |
80 | | match never {} |
81 | | } |
82 | | } |
83 | | |
84 | | /// An error type returned when an integer cannot be parsed (mimics [std::num::ParseIntError]) |
85 | | #[derive(Clone, Debug, PartialEq, Eq)] |
86 | | pub struct ParseIntError(()); |
87 | | |
88 | | #[cfg(feature = "std")] |
89 | | impl std::error::Error for ParseIntError {} |
90 | | |
91 | | impl core::fmt::Display for ParseIntError { |
92 | 0 | fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { |
93 | 0 | "unable to parse integer".fmt(fmt) |
94 | 0 | } |
95 | | } |
96 | | |
97 | | impl From<core::num::ParseIntError> for ParseIntError { |
98 | 0 | fn from(_: core::num::ParseIntError) -> Self { |
99 | 0 | Self(()) |
100 | 0 | } |
101 | | } |
102 | | |
103 | | // error[E0658]: the `!` type is experimental |
104 | | // https://github.com/rust-lang/rust/issues/35121 |
105 | | // impl From<!> for TryFromIntError { ... } |
106 | | |
107 | | // https://doc.rust-lang.org/1.47.0/src/core/num/mod.rs.html#31-43 |
108 | | macro_rules! impl_nonmax_fmt { |
109 | | ( ( $( $Trait: ident ),+ ) for $nonmax: ident ) => { |
110 | | $( |
111 | | impl core::fmt::$Trait for $nonmax { |
112 | | #[inline] |
113 | 0 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
114 | 0 | core::fmt::$Trait::fmt(&self.get(), f) |
115 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI64 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxI64 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxI64 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxI64 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxI64 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI64 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI128 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxI128 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxI128 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxI32 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxI32 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxI32 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxI32 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxI32 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI32 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI128 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxI128 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI128 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU8 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxU8 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxU8 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxU8 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxU8 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU8 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxIsize as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxIsize as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxIsize as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxIsize as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxIsize as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxIsize as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU16 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxU32 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxU32 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxU32 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxU32 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU32 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU64 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxU16 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxU16 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxU16 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxU16 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU16 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU32 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxU64 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxU64 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxU64 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxU64 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU64 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxUsize as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxUsize as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxUsize as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxUsize as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxUsize as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxUsize as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU128 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxU128 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxU128 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxU128 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxU128 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxU128 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI8 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxI8 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI8 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI16 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxI16 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxI16 as core::fmt::Binary>::fmt Unexecuted instantiation: <nonmax::NonMaxI16 as core::fmt::Octal>::fmt Unexecuted instantiation: <nonmax::NonMaxI16 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI16 as core::fmt::UpperHex>::fmt Unexecuted instantiation: <nonmax::NonMaxI8 as core::fmt::Debug>::fmt Unexecuted instantiation: <nonmax::NonMaxI8 as core::fmt::Display>::fmt Unexecuted instantiation: <nonmax::NonMaxI8 as core::fmt::Binary>::fmt |
116 | | } |
117 | | )+ |
118 | | }; |
119 | | } |
120 | | |
121 | | macro_rules! nonmax { |
122 | | ( common, $nonmax: ident, $non_zero: ident, $primitive: ident ) => { |
123 | | /// An integer that is known not to equal its maximum value. |
124 | | #[derive(Clone, Copy, PartialEq, Eq, Hash)] |
125 | | #[repr(transparent)] |
126 | | pub struct $nonmax(core::num::$non_zero); |
127 | | |
128 | | impl $nonmax { |
129 | | /// Creates a new non-max if the given value is not the maximum |
130 | | /// value. |
131 | | #[inline] |
132 | 193M | pub const fn new(value: $primitive) -> Option<Self> { |
133 | 193M | match core::num::$non_zero::new(value ^ $primitive::MAX) { |
134 | 0 | None => None, |
135 | 193M | Some(value) => Some(Self(value)), |
136 | | } |
137 | 193M | } Unexecuted instantiation: <nonmax::NonMaxU32>::new Unexecuted instantiation: <nonmax::NonMaxU32>::new Unexecuted instantiation: <nonmax::NonMaxU32>::new Line | Count | Source | 132 | 3.92M | pub const fn new(value: $primitive) -> Option<Self> { | 133 | 3.92M | match core::num::$non_zero::new(value ^ $primitive::MAX) { | 134 | 0 | None => None, | 135 | 3.92M | Some(value) => Some(Self(value)), | 136 | | } | 137 | 3.92M | } |
Line | Count | Source | 132 | 190M | pub const fn new(value: $primitive) -> Option<Self> { | 133 | 190M | match core::num::$non_zero::new(value ^ $primitive::MAX) { | 134 | 0 | None => None, | 135 | 190M | Some(value) => Some(Self(value)), | 136 | | } | 137 | 190M | } |
Unexecuted instantiation: <nonmax::NonMaxU32>::new Unexecuted instantiation: <nonmax::NonMaxI128>::new Unexecuted instantiation: <nonmax::NonMaxI64>::new Unexecuted instantiation: <nonmax::NonMaxIsize>::new Unexecuted instantiation: <nonmax::NonMaxU16>::new Unexecuted instantiation: <nonmax::NonMaxU8>::new Unexecuted instantiation: <nonmax::NonMaxU64>::new Unexecuted instantiation: <nonmax::NonMaxU32>::new Unexecuted instantiation: <nonmax::NonMaxU128>::new Unexecuted instantiation: <nonmax::NonMaxUsize>::new Unexecuted instantiation: <nonmax::NonMaxI16>::new Unexecuted instantiation: <nonmax::NonMaxI32>::new Unexecuted instantiation: <nonmax::NonMaxI8>::new |
138 | | |
139 | | /// Creates a new non-max without checking the value. |
140 | | /// |
141 | | /// # Safety |
142 | | /// |
143 | | /// The value must not equal the maximum representable value for the |
144 | | /// primitive type. |
145 | | #[inline] |
146 | 11.8M | pub const unsafe fn new_unchecked(value: $primitive) -> Self { |
147 | 11.8M | let inner = core::num::$non_zero::new_unchecked(value ^ $primitive::MAX); |
148 | 11.8M | Self(inner) |
149 | 11.8M | } Unexecuted instantiation: <nonmax::NonMaxU32>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxU32>::new_unchecked <nonmax::NonMaxU32>::new_unchecked Line | Count | Source | 146 | 2.53M | pub const unsafe fn new_unchecked(value: $primitive) -> Self { | 147 | 2.53M | let inner = core::num::$non_zero::new_unchecked(value ^ $primitive::MAX); | 148 | 2.53M | Self(inner) | 149 | 2.53M | } |
<nonmax::NonMaxU32>::new_unchecked Line | Count | Source | 146 | 9.33M | pub const unsafe fn new_unchecked(value: $primitive) -> Self { | 147 | 9.33M | let inner = core::num::$non_zero::new_unchecked(value ^ $primitive::MAX); | 148 | 9.33M | Self(inner) | 149 | 9.33M | } |
Unexecuted instantiation: <nonmax::NonMaxU32>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxI128>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxI64>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxIsize>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxU16>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxU8>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxU64>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxU32>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxU128>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxUsize>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxI16>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxI32>::new_unchecked Unexecuted instantiation: <nonmax::NonMaxI8>::new_unchecked |
150 | | |
151 | | /// Returns the value as a primitive type. |
152 | | #[inline] |
153 | 18.1M | pub const fn get(&self) -> $primitive { |
154 | 18.1M | self.0.get() ^ $primitive::MAX |
155 | 18.1M | } Unexecuted instantiation: <nonmax::NonMaxU32>::get Unexecuted instantiation: <nonmax::NonMaxU32>::get Unexecuted instantiation: <nonmax::NonMaxU32>::get Unexecuted instantiation: <nonmax::NonMaxU32>::get Line | Count | Source | 153 | 4.12M | pub const fn get(&self) -> $primitive { | 154 | 4.12M | self.0.get() ^ $primitive::MAX | 155 | 4.12M | } |
Line | Count | Source | 153 | 14.0M | pub const fn get(&self) -> $primitive { | 154 | 14.0M | self.0.get() ^ $primitive::MAX | 155 | 14.0M | } |
Unexecuted instantiation: <nonmax::NonMaxU32>::get Unexecuted instantiation: <nonmax::NonMaxU32>::get Unexecuted instantiation: <nonmax::NonMaxI128>::get Unexecuted instantiation: <nonmax::NonMaxI64>::get Unexecuted instantiation: <nonmax::NonMaxIsize>::get Unexecuted instantiation: <nonmax::NonMaxU16>::get Unexecuted instantiation: <nonmax::NonMaxU8>::get Unexecuted instantiation: <nonmax::NonMaxU64>::get Unexecuted instantiation: <nonmax::NonMaxU32>::get Unexecuted instantiation: <nonmax::NonMaxU128>::get Unexecuted instantiation: <nonmax::NonMaxUsize>::get Unexecuted instantiation: <nonmax::NonMaxI16>::get Unexecuted instantiation: <nonmax::NonMaxI32>::get Unexecuted instantiation: <nonmax::NonMaxI8>::get |
156 | | |
157 | | /// Gets non-max with the value zero (0) |
158 | | pub const ZERO: $nonmax = unsafe { Self::new_unchecked(0) }; |
159 | | |
160 | | /// Gets non-max with the value one (1) |
161 | | pub const ONE: $nonmax = unsafe { Self::new_unchecked(1) }; |
162 | | |
163 | | /// Gets non-max with maximum possible value (which is maximum of the underlying primitive minus one) |
164 | | pub const MAX: $nonmax = unsafe { Self::new_unchecked($primitive::MAX - 1) }; |
165 | | } |
166 | | |
167 | | impl Default for $nonmax { |
168 | 0 | fn default() -> Self { |
169 | 0 | unsafe { Self::new_unchecked(0) } |
170 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxI128 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxI64 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxIsize as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxU16 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxU8 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxU64 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxU32 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxUsize as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxU128 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxI16 as core::default::Default>::default Unexecuted instantiation: <nonmax::NonMaxI8 as core::default::Default>::default |
171 | | } |
172 | | |
173 | | impl From<$nonmax> for $primitive { |
174 | 0 | fn from(value: $nonmax) -> Self { |
175 | 0 | value.get() |
176 | 0 | } Unexecuted instantiation: <i32 as core::convert::From<nonmax::NonMaxI32>>::from Unexecuted instantiation: <i128 as core::convert::From<nonmax::NonMaxI128>>::from Unexecuted instantiation: <i64 as core::convert::From<nonmax::NonMaxI64>>::from Unexecuted instantiation: <isize as core::convert::From<nonmax::NonMaxIsize>>::from Unexecuted instantiation: <u16 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <u8 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <u64 as core::convert::From<nonmax::NonMaxU64>>::from Unexecuted instantiation: <u32 as core::convert::From<nonmax::NonMaxU32>>::from Unexecuted instantiation: <usize as core::convert::From<nonmax::NonMaxUsize>>::from Unexecuted instantiation: <u128 as core::convert::From<nonmax::NonMaxU128>>::from Unexecuted instantiation: <i16 as core::convert::From<nonmax::NonMaxI16>>::from Unexecuted instantiation: <i8 as core::convert::From<nonmax::NonMaxI8>>::from |
177 | | } |
178 | | |
179 | | impl core::convert::TryFrom<$primitive> for $nonmax { |
180 | | type Error = TryFromIntError; |
181 | 0 | fn try_from(value: $primitive) -> Result<Self, Self::Error> { |
182 | 0 | Self::new(value).ok_or(TryFromIntError(())) |
183 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::TryFrom<i32>>::try_from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::TryFrom<i128>>::try_from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::TryFrom<i64>>::try_from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::TryFrom<isize>>::try_from Unexecuted instantiation: <nonmax::NonMaxU16 as core::convert::TryFrom<u16>>::try_from Unexecuted instantiation: <nonmax::NonMaxU8 as core::convert::TryFrom<u8>>::try_from Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::TryFrom<u64>>::try_from Unexecuted instantiation: <nonmax::NonMaxU32 as core::convert::TryFrom<u32>>::try_from Unexecuted instantiation: <nonmax::NonMaxUsize as core::convert::TryFrom<usize>>::try_from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::TryFrom<u128>>::try_from Unexecuted instantiation: <nonmax::NonMaxI16 as core::convert::TryFrom<i16>>::try_from Unexecuted instantiation: <nonmax::NonMaxI8 as core::convert::TryFrom<i8>>::try_from |
184 | | } |
185 | | |
186 | | impl core::str::FromStr for $nonmax { |
187 | | type Err = ParseIntError; |
188 | 0 | fn from_str(value: &str) -> Result<Self, Self::Err> { |
189 | 0 | Self::new($primitive::from_str(value)?).ok_or(ParseIntError(())) |
190 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxI128 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxI64 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxIsize as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxU16 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxU8 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxU64 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxU32 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxUsize as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxU128 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxI16 as core::str::traits::FromStr>::from_str Unexecuted instantiation: <nonmax::NonMaxI8 as core::str::traits::FromStr>::from_str |
191 | | } |
192 | | |
193 | | impl core::cmp::Ord for $nonmax { |
194 | 0 | fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
195 | 0 | self.get().cmp(&other.get()) |
196 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxI128 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxI64 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxIsize as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxU16 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxU8 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxU64 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxU32 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxUsize as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxU128 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxI16 as core::cmp::Ord>::cmp Unexecuted instantiation: <nonmax::NonMaxI8 as core::cmp::Ord>::cmp |
197 | | } |
198 | | impl core::cmp::PartialOrd for $nonmax { |
199 | 0 | fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { |
200 | 0 | Some(self.cmp(other)) |
201 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxI128 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxI64 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxIsize as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxU16 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxU8 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxU64 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxU32 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxUsize as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxU128 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxI16 as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <nonmax::NonMaxI8 as core::cmp::PartialOrd>::partial_cmp |
202 | | } |
203 | | |
204 | | // NonZero can implement BitOr (will never 0 a nonzero value) but not BitAnd. |
205 | | // NonMax can implement BitAnd but not BitOr, with some caveats for signed values: |
206 | | // -1 (11...11) & max (01...11) can result in signed max (01...11), so both operands must be nonmax for signed variants |
207 | | |
208 | | impl core::ops::BitAnd<$nonmax> for $nonmax { |
209 | | type Output = $nonmax; |
210 | 0 | fn bitand(self, rhs: $nonmax) -> Self::Output { |
211 | | // Safety: since `rhs` is non-max, the result of the |
212 | | // bitwise-and will be non-max regardless of the value of `self` |
213 | 0 | unsafe { $nonmax::new_unchecked(self.get() & rhs.get()) } |
214 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxI128 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxI64 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxU8 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxIsize as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxU16 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxU64 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxU32 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxUsize as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxU128 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxI16 as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <nonmax::NonMaxI8 as core::ops::bit::BitAnd>::bitand |
215 | | } |
216 | | |
217 | | impl core::ops::BitAndAssign<$nonmax> for $nonmax { |
218 | 0 | fn bitand_assign(&mut self, rhs: $nonmax) { |
219 | 0 | *self = *self & rhs; |
220 | 0 | } Unexecuted instantiation: <nonmax::NonMaxI32 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxI128 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxI64 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU8 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxIsize as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU16 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU64 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU32 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxUsize as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU128 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxI16 as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxI8 as core::ops::bit::BitAndAssign>::bitand_assign |
221 | | } |
222 | | |
223 | | // https://doc.rust-lang.org/1.47.0/src/core/num/mod.rs.html#173-175 |
224 | | impl_nonmax_fmt! { |
225 | | (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $nonmax |
226 | | } |
227 | | |
228 | | #[cfg(feature = "serde")] |
229 | | impl serde::Serialize for $nonmax { |
230 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
231 | | where |
232 | | S: serde::Serializer, |
233 | | { |
234 | | self.get().serialize(serializer) |
235 | | } |
236 | | } |
237 | | |
238 | | #[cfg(feature = "serde")] |
239 | | impl<'de> serde::Deserialize<'de> for $nonmax { |
240 | | fn deserialize<D>(deserializer: D) -> Result<$nonmax, D::Error> |
241 | | where |
242 | | D: serde::Deserializer<'de>, |
243 | | { |
244 | | let value = $primitive::deserialize(deserializer)?; |
245 | | use core::convert::TryFrom; |
246 | | Self::try_from(value).map_err(serde::de::Error::custom) |
247 | | } |
248 | | } |
249 | | |
250 | | #[cfg(test)] |
251 | | mod $primitive { |
252 | | use super::*; |
253 | | |
254 | | use core::mem::size_of; |
255 | | |
256 | | #[test] |
257 | | fn construct() { |
258 | | let zero = $nonmax::new(0).unwrap(); |
259 | | assert_eq!(zero.get(), 0); |
260 | | |
261 | | let some = $nonmax::new(19).unwrap(); |
262 | | assert_eq!(some.get(), 19); |
263 | | |
264 | | let max = $nonmax::new($primitive::MAX); |
265 | | assert_eq!(max, None); |
266 | | } |
267 | | |
268 | | #[test] |
269 | | fn sizes_correct() { |
270 | | assert_eq!(size_of::<$primitive>(), size_of::<$nonmax>()); |
271 | | assert_eq!(size_of::<$nonmax>(), size_of::<Option<$nonmax>>()); |
272 | | } |
273 | | |
274 | | #[test] |
275 | | fn convert() { |
276 | | use core::convert::TryFrom; |
277 | | let zero = $nonmax::try_from(0 as $primitive).unwrap(); |
278 | | let zero = $primitive::from(zero); |
279 | | assert_eq!(zero, 0); |
280 | | |
281 | | $nonmax::try_from($primitive::MAX).unwrap_err(); |
282 | | } |
283 | | |
284 | | #[test] |
285 | | fn cmp() { |
286 | | let zero = $nonmax::new(0).unwrap(); |
287 | | let one = $nonmax::new(1).unwrap(); |
288 | | let two = $nonmax::new(2).unwrap(); |
289 | | assert!(zero < one); |
290 | | assert!(one < two); |
291 | | assert!(two > one); |
292 | | assert!(one > zero); |
293 | | } |
294 | | |
295 | | #[test] |
296 | | fn constants() { |
297 | | let zero = $nonmax::ZERO; |
298 | | let one = $nonmax::ONE; |
299 | | let max = $nonmax::MAX; |
300 | | assert_eq!(zero.get(), 0); |
301 | | assert_eq!(one.get(), 1); |
302 | | assert_eq!(max.get(), $primitive::MAX - 1); |
303 | | } |
304 | | |
305 | | #[test] |
306 | | #[cfg(feature = "std")] // to_string |
307 | | fn parse() { |
308 | | for value in [0, 19, $primitive::MAX - 1].iter().copied() { |
309 | | let string = value.to_string(); |
310 | | let nonmax = string.parse::<$nonmax>().unwrap(); |
311 | | assert_eq!(nonmax.get(), value); |
312 | | } |
313 | | $primitive::MAX.to_string().parse::<$nonmax>().unwrap_err(); |
314 | | } |
315 | | |
316 | | #[test] |
317 | | #[cfg(feature = "std")] // format! |
318 | | fn fmt() { |
319 | | let zero = $nonmax::new(0).unwrap(); |
320 | | let some = $nonmax::new(19).unwrap(); |
321 | | let max1 = $nonmax::new($primitive::MAX - 1).unwrap(); |
322 | | for value in [zero, some, max1].iter().copied() { |
323 | | assert_eq!(format!("{}", value.get()), format!("{}", value)); // Display |
324 | | assert_eq!(format!("{:?}", value.get()), format!("{:?}", value)); // Debug |
325 | | assert_eq!(format!("{:b}", value.get()), format!("{:b}", value)); // Binary |
326 | | assert_eq!(format!("{:o}", value.get()), format!("{:o}", value)); // Octal |
327 | | assert_eq!(format!("{:x}", value.get()), format!("{:x}", value)); // LowerHex |
328 | | assert_eq!(format!("{:X}", value.get()), format!("{:X}", value)); // UpperHex |
329 | | } |
330 | | } |
331 | | |
332 | | #[test] |
333 | | #[cfg(feature = "serde")] |
334 | | fn serde() { |
335 | | for &value in [0, 19, $primitive::MAX - 1].iter() { |
336 | | let nonmax_value = $nonmax::new(value).unwrap(); |
337 | | let encoded: Vec<u8> = bincode::serialize(&nonmax_value).unwrap(); |
338 | | let decoded: $nonmax = bincode::deserialize(&encoded[..]).unwrap(); |
339 | | assert_eq!(nonmax_value, decoded); |
340 | | } |
341 | | } |
342 | | } |
343 | | }; |
344 | | |
345 | | ( signed, $nonmax: ident, $non_zero: ident, $primitive: ident ) => { |
346 | | nonmax!(common, $nonmax, $non_zero, $primitive); |
347 | | // Nothing unique to signed versions (yet) |
348 | | }; |
349 | | |
350 | | ( unsigned, $nonmax: ident, $non_zero: ident, $primitive: ident ) => { |
351 | | nonmax!(common, $nonmax, $non_zero, $primitive); |
352 | | |
353 | | impl core::ops::BitAnd<$nonmax> for $primitive { |
354 | | type Output = $nonmax; |
355 | 0 | fn bitand(self, rhs: $nonmax) -> Self::Output { |
356 | | // Safety: since `rhs` is non-max, the result of the |
357 | | // bitwise-and will be non-max regardless of the value of `self` |
358 | 0 | unsafe { $nonmax::new_unchecked(self & rhs.get()) } |
359 | 0 | } Unexecuted instantiation: <u16 as core::ops::bit::BitAnd<nonmax::NonMaxU16>>::bitand Unexecuted instantiation: <u8 as core::ops::bit::BitAnd<nonmax::NonMaxU8>>::bitand Unexecuted instantiation: <u64 as core::ops::bit::BitAnd<nonmax::NonMaxU64>>::bitand Unexecuted instantiation: <u32 as core::ops::bit::BitAnd<nonmax::NonMaxU32>>::bitand Unexecuted instantiation: <u128 as core::ops::bit::BitAnd<nonmax::NonMaxU128>>::bitand Unexecuted instantiation: <usize as core::ops::bit::BitAnd<nonmax::NonMaxUsize>>::bitand |
360 | | } |
361 | | |
362 | | impl core::ops::BitAnd<$primitive> for $nonmax { |
363 | | type Output = $nonmax; |
364 | 0 | fn bitand(self, rhs: $primitive) -> Self::Output { |
365 | | // Safety: since `self` is non-max, the result of the |
366 | | // bitwise-and will be non-max regardless of the value of `rhs` |
367 | 0 | unsafe { $nonmax::new_unchecked(self.get() & rhs) } |
368 | 0 | } Unexecuted instantiation: <nonmax::NonMaxU16 as core::ops::bit::BitAnd<u16>>::bitand Unexecuted instantiation: <nonmax::NonMaxU8 as core::ops::bit::BitAnd<u8>>::bitand Unexecuted instantiation: <nonmax::NonMaxU64 as core::ops::bit::BitAnd<u64>>::bitand Unexecuted instantiation: <nonmax::NonMaxU32 as core::ops::bit::BitAnd<u32>>::bitand Unexecuted instantiation: <nonmax::NonMaxU128 as core::ops::bit::BitAnd<u128>>::bitand Unexecuted instantiation: <nonmax::NonMaxUsize as core::ops::bit::BitAnd<usize>>::bitand |
369 | | } |
370 | | |
371 | | impl core::ops::BitAndAssign<$primitive> for $nonmax { |
372 | 0 | fn bitand_assign(&mut self, rhs: $primitive) { |
373 | 0 | *self = *self & rhs; |
374 | 0 | } Unexecuted instantiation: <nonmax::NonMaxU16 as core::ops::bit::BitAndAssign<u16>>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU8 as core::ops::bit::BitAndAssign<u8>>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU64 as core::ops::bit::BitAndAssign<u64>>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU32 as core::ops::bit::BitAndAssign<u32>>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxU128 as core::ops::bit::BitAndAssign<u128>>::bitand_assign Unexecuted instantiation: <nonmax::NonMaxUsize as core::ops::bit::BitAndAssign<usize>>::bitand_assign |
375 | | } |
376 | | |
377 | | // std doesn't have an equivalent BitAndOr for $nonzero, but this just makes sense |
378 | | impl core::ops::BitAndAssign<$nonmax> for $primitive { |
379 | 0 | fn bitand_assign(&mut self, rhs: $nonmax) { |
380 | 0 | *self = *self & rhs.get(); |
381 | 0 | } Unexecuted instantiation: <u16 as core::ops::bit::BitAndAssign<nonmax::NonMaxU16>>::bitand_assign Unexecuted instantiation: <u8 as core::ops::bit::BitAndAssign<nonmax::NonMaxU8>>::bitand_assign Unexecuted instantiation: <u64 as core::ops::bit::BitAndAssign<nonmax::NonMaxU64>>::bitand_assign Unexecuted instantiation: <u32 as core::ops::bit::BitAndAssign<nonmax::NonMaxU32>>::bitand_assign Unexecuted instantiation: <u128 as core::ops::bit::BitAndAssign<nonmax::NonMaxU128>>::bitand_assign Unexecuted instantiation: <usize as core::ops::bit::BitAndAssign<nonmax::NonMaxUsize>>::bitand_assign |
382 | | } |
383 | | }; |
384 | | } |
385 | | |
386 | | nonmax!(signed, NonMaxI8, NonZeroI8, i8); |
387 | | nonmax!(signed, NonMaxI16, NonZeroI16, i16); |
388 | | nonmax!(signed, NonMaxI32, NonZeroI32, i32); |
389 | | nonmax!(signed, NonMaxI64, NonZeroI64, i64); |
390 | | nonmax!(signed, NonMaxI128, NonZeroI128, i128); |
391 | | nonmax!(signed, NonMaxIsize, NonZeroIsize, isize); |
392 | | |
393 | | nonmax!(unsigned, NonMaxU8, NonZeroU8, u8); |
394 | | nonmax!(unsigned, NonMaxU16, NonZeroU16, u16); |
395 | | nonmax!(unsigned, NonMaxU32, NonZeroU32, u32); |
396 | | nonmax!(unsigned, NonMaxU64, NonZeroU64, u64); |
397 | | nonmax!(unsigned, NonMaxU128, NonZeroU128, u128); |
398 | | nonmax!(unsigned, NonMaxUsize, NonZeroUsize, usize); |
399 | | |
400 | | // https://doc.rust-lang.org/1.47.0/src/core/convert/num.rs.html#383-407 |
401 | | macro_rules! impl_nonmax_from { |
402 | | ( $small: ty, $large: ty ) => { |
403 | | impl From<$small> for $large { |
404 | | #[inline] |
405 | 0 | fn from(small: $small) -> Self { |
406 | | // SAFETY: smaller input type guarantees the value is non-max |
407 | 0 | unsafe { Self::new_unchecked(small.get().into()) } |
408 | 0 | } Unexecuted instantiation: <nonmax::NonMaxU16 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxU32 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxUsize as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxU32 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxUsize as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::From<nonmax::NonMaxU32>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<nonmax::NonMaxU32>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<nonmax::NonMaxU64>>::from Unexecuted instantiation: <nonmax::NonMaxI16 as core::convert::From<nonmax::NonMaxI8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<nonmax::NonMaxI8>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<nonmax::NonMaxI8>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxI8>>::from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::From<nonmax::NonMaxI8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<nonmax::NonMaxI16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<nonmax::NonMaxI16>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxI16>>::from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::From<nonmax::NonMaxI16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<nonmax::NonMaxI32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxI32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxI64>>::from Unexecuted instantiation: <nonmax::NonMaxI16 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::From<nonmax::NonMaxU8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxU16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<nonmax::NonMaxU32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxU32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<nonmax::NonMaxU64>>::from |
409 | | } |
410 | | }; |
411 | | } |
412 | | |
413 | | // Non-max Unsigned -> Non-max Unsigned |
414 | | impl_nonmax_from!(NonMaxU8, NonMaxU16); |
415 | | impl_nonmax_from!(NonMaxU8, NonMaxU32); |
416 | | impl_nonmax_from!(NonMaxU8, NonMaxU64); |
417 | | impl_nonmax_from!(NonMaxU8, NonMaxU128); |
418 | | impl_nonmax_from!(NonMaxU8, NonMaxUsize); |
419 | | impl_nonmax_from!(NonMaxU16, NonMaxU32); |
420 | | impl_nonmax_from!(NonMaxU16, NonMaxU64); |
421 | | impl_nonmax_from!(NonMaxU16, NonMaxU128); |
422 | | impl_nonmax_from!(NonMaxU16, NonMaxUsize); |
423 | | impl_nonmax_from!(NonMaxU32, NonMaxU64); |
424 | | impl_nonmax_from!(NonMaxU32, NonMaxU128); |
425 | | impl_nonmax_from!(NonMaxU64, NonMaxU128); |
426 | | |
427 | | // Non-max Signed -> Non-max Signed |
428 | | impl_nonmax_from!(NonMaxI8, NonMaxI16); |
429 | | impl_nonmax_from!(NonMaxI8, NonMaxI32); |
430 | | impl_nonmax_from!(NonMaxI8, NonMaxI64); |
431 | | impl_nonmax_from!(NonMaxI8, NonMaxI128); |
432 | | impl_nonmax_from!(NonMaxI8, NonMaxIsize); |
433 | | impl_nonmax_from!(NonMaxI16, NonMaxI32); |
434 | | impl_nonmax_from!(NonMaxI16, NonMaxI64); |
435 | | impl_nonmax_from!(NonMaxI16, NonMaxI128); |
436 | | impl_nonmax_from!(NonMaxI16, NonMaxIsize); |
437 | | impl_nonmax_from!(NonMaxI32, NonMaxI64); |
438 | | impl_nonmax_from!(NonMaxI32, NonMaxI128); |
439 | | impl_nonmax_from!(NonMaxI64, NonMaxI128); |
440 | | |
441 | | // Non-max Unsigned -> Non-max Signed |
442 | | impl_nonmax_from!(NonMaxU8, NonMaxI16); |
443 | | impl_nonmax_from!(NonMaxU8, NonMaxI32); |
444 | | impl_nonmax_from!(NonMaxU8, NonMaxI64); |
445 | | impl_nonmax_from!(NonMaxU8, NonMaxI128); |
446 | | impl_nonmax_from!(NonMaxU8, NonMaxIsize); |
447 | | impl_nonmax_from!(NonMaxU16, NonMaxI32); |
448 | | impl_nonmax_from!(NonMaxU16, NonMaxI64); |
449 | | impl_nonmax_from!(NonMaxU16, NonMaxI128); |
450 | | impl_nonmax_from!(NonMaxU32, NonMaxI64); |
451 | | impl_nonmax_from!(NonMaxU32, NonMaxI128); |
452 | | impl_nonmax_from!(NonMaxU64, NonMaxI128); |
453 | | |
454 | | // https://doc.rust-lang.org/1.47.0/src/core/convert/num.rs.html#383-407 |
455 | | macro_rules! impl_smaller_from { |
456 | | ( $small: ty, $large: ty ) => { |
457 | | impl From<$small> for $large { |
458 | | #[inline] |
459 | 0 | fn from(small: $small) -> Self { |
460 | | // SAFETY: smaller input type guarantees the value is non-max |
461 | 0 | unsafe { Self::new_unchecked(small.into()) } |
462 | 0 | } Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxUsize as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::From<u32>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<u32>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<u64>>::from Unexecuted instantiation: <nonmax::NonMaxI16 as core::convert::From<i8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<i8>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<i8>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<i8>>::from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::From<i8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<i16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<i16>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<i16>>::from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::From<i16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<i32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<i32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<i64>>::from Unexecuted instantiation: <nonmax::NonMaxI16 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxIsize as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxI32 as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxU16 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxU32 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxU64 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxU128 as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxUsize as core::convert::From<u8>>::from Unexecuted instantiation: <nonmax::NonMaxU32 as core::convert::From<u16>>::from Unexecuted instantiation: <nonmax::NonMaxI64 as core::convert::From<u32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<u32>>::from Unexecuted instantiation: <nonmax::NonMaxI128 as core::convert::From<u64>>::from |
463 | | } |
464 | | }; |
465 | | } |
466 | | |
467 | | // Unsigned -> Non-max Unsigned |
468 | | impl_smaller_from!(u8, NonMaxU16); |
469 | | impl_smaller_from!(u8, NonMaxU32); |
470 | | impl_smaller_from!(u8, NonMaxU64); |
471 | | impl_smaller_from!(u8, NonMaxU128); |
472 | | impl_smaller_from!(u8, NonMaxUsize); |
473 | | impl_smaller_from!(u16, NonMaxU32); |
474 | | impl_smaller_from!(u16, NonMaxU64); |
475 | | impl_smaller_from!(u16, NonMaxU128); |
476 | | impl_smaller_from!(u16, NonMaxUsize); |
477 | | impl_smaller_from!(u32, NonMaxU64); |
478 | | impl_smaller_from!(u32, NonMaxU128); |
479 | | impl_smaller_from!(u64, NonMaxU128); |
480 | | |
481 | | // Signed -> Non-max Signed |
482 | | impl_smaller_from!(i8, NonMaxI16); |
483 | | impl_smaller_from!(i8, NonMaxI32); |
484 | | impl_smaller_from!(i8, NonMaxI64); |
485 | | impl_smaller_from!(i8, NonMaxI128); |
486 | | impl_smaller_from!(i8, NonMaxIsize); |
487 | | impl_smaller_from!(i16, NonMaxI32); |
488 | | impl_smaller_from!(i16, NonMaxI64); |
489 | | impl_smaller_from!(i16, NonMaxI128); |
490 | | impl_smaller_from!(i16, NonMaxIsize); |
491 | | impl_smaller_from!(i32, NonMaxI64); |
492 | | impl_smaller_from!(i32, NonMaxI128); |
493 | | impl_smaller_from!(i64, NonMaxI128); |
494 | | |
495 | | // Unsigned -> Non-max Signed |
496 | | impl_smaller_from!(u8, NonMaxI16); |
497 | | impl_smaller_from!(u8, NonMaxI32); |
498 | | impl_smaller_from!(u8, NonMaxI64); |
499 | | impl_smaller_from!(u8, NonMaxI128); |
500 | | impl_smaller_from!(u8, NonMaxIsize); |
501 | | impl_smaller_from!(u16, NonMaxI32); |
502 | | impl_smaller_from!(u16, NonMaxI64); |
503 | | impl_smaller_from!(u16, NonMaxI128); |
504 | | impl_smaller_from!(u32, NonMaxI64); |
505 | | impl_smaller_from!(u32, NonMaxI128); |
506 | | impl_smaller_from!(u64, NonMaxI128); |
507 | | |
508 | | #[cfg(test)] |
509 | | mod ops { |
510 | | use super::*; |
511 | | |
512 | | #[test] |
513 | | fn bitand_unsigned() { |
514 | | for left in 0..=u8::MAX { |
515 | | let nmleft = NonMaxU8::new(left); |
516 | | for right in 0..=u8::MAX { |
517 | | let nmright = NonMaxU8::new(right); |
518 | | let vanilla = left & right; |
519 | | |
520 | | if let (Some(nmleft), Some(nmright)) = (nmleft, nmright) { |
521 | | assert_eq!(vanilla, (nmleft & nmright).get()); |
522 | | } |
523 | | if let Some(nmleft) = nmleft { |
524 | | assert_eq!(vanilla, (nmleft & right).get()); |
525 | | } |
526 | | if let Some(nmright) = nmright { |
527 | | assert_eq!(vanilla, (left & nmright).get()); |
528 | | } |
529 | | } |
530 | | } |
531 | | } |
532 | | |
533 | | #[test] |
534 | | fn bitand_signed() { |
535 | | for left in i8::MIN..=i8::MAX { |
536 | | let nmleft = NonMaxI8::new(left); |
537 | | for right in i8::MIN..=i8::MAX { |
538 | | let nmright = NonMaxI8::new(right); |
539 | | let vanilla = left & right; |
540 | | if let (Some(nmleft), Some(nmright)) = (nmleft, nmright) { |
541 | | assert_eq!(vanilla, (nmleft & nmright).get()); |
542 | | } |
543 | | } |
544 | | } |
545 | | } |
546 | | } |