Coverage Report

Created: 2026-10-28 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nonmax-0.5.5/src/lib.rs
Line
Count
Source
1
/*!
2
[![GitHub CI Status](https://github.com/LPGhatguy/nonmax/workflows/CI/badge.svg)](https://github.com/LPGhatguy/nonmax/actions)
3
[![nonmax on crates.io](https://img.shields.io/crates/v/nonmax.svg)](https://crates.io/crates/nonmax)
4
[![nonmax docs](https://img.shields.io/badge/docs-docs.rs-orange.svg)](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
<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
            }
<nonmax::NonMaxU32>::new
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
<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
            }
<nonmax::NonMaxU32>::get
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
}