| Crates.io | nonmaxunsigned |
| lib.rs | nonmaxunsigned |
| version | 2.0.0 |
| created_at | 2025-07-09 19:46:01.411158+00 |
| updated_at | 2025-07-14 22:09:48.450011+00 |
| description | A NonMax integer implementation not relying on NonZero |
| homepage | |
| repository | https://github.com/Wasabi375/nonmaxunsigned |
| max_upload_size | |
| id | 1745371 |
| size | 92,307 |
This crate provides an implementation for non-max integer types with null-pointer-optimization and ensures that the binary representation of the non-max and the normal integers are the same.
This crate is usable in a no-std environment.
[!WARNING] This crate relies on undefined behaviour in the rust compiler and there is no guarantee that this will continue to work in the future.
use nonmaxunsigned::NonMaxU8;
fn main() {
let a = NonMaxU8::new(5).unwrap();
let b = NonMaxU8::new(12).unwrap();
assert_eq!(NonMaxU8::new(17).unwrap(), a + b);
assert_eq!(None, NonMaxU8::new(u8::MAX));
}
The maximum value for the non-max integers is lower than just max - 1.
This is neccessary to ensure that the binary representation is the same as the
normal integers.
The maximum value for each non-max version is as follows:
| Integer | Hex | Decimal | Difference Hex | Difference Decimal |
|---|---|---|---|---|
u8 |
0xfe |
255 | 0x1 |
1 |
u16 |
0xfeff |
65279 | 0x100 |
256 |
u32 |
0xfeff_ffff |
4278190079 | 0x100_0000 |
116777216 |
u64 |
0xfeff_ffff_ffff_ffff |
18374686479671623679 | 0x100_0000_0000_0000 |
72057594037927936 |
This feature provides access to little and big endian versions of the non-max integer types as well as conversions between them. The native version for the non-max integers is just a type alias for the correct endianness.
non_max.get() will always return the native endian integer.
#[cfg(feature = "endian-conversion")]
use nonmaxunsigned::{NonMaxU32Le, NonMaxU32Be, NonMaxU32};
#[cfg(feature = "endian-conversion")]
fn main() {
let native = NonMaxU32::new(37).unwrap();
let little = native.to_le();
let big = native.to_be();
assert_eq!(little.get(), big.get());
assert_eq!(native.get(), big.get());
assert_eq!(native.get(), little.get());
assert_eq!(little.to_native(), native);
assert_eq!(little.to_be(), big);
assert_eq!(little.get_underlying(), 37u32.to_le());
assert_eq!(big.get_underlying(), 37u32.to_be());
}
#[cfg(not(feature = "endian-conversion"))]
fn main() {}
There are a few similar crates already existing on crates.io:
Unlike those crates this implementation does not NonZero.
Those crates store the value as value ^ max which is never 0 as long as value != max.
However this means the binary/hex representation of the stored value is hard to parse.
This implementation instead relies on a large enum NonMaxU8Internal which has 254 variants.
Such an enum also leads to null-pointer-optimization but does not require the xor trick
to prevent 0 values.
Instead it relies on core::mem::transmute_copy.
Licensed under either of
at your option.