1#![cfg_attr(not(feature = "std"), no_std)]
6
7mod error;
8mod helpers;
9
10pub use error::Error;
11
12use core::num::{NonZeroU128, NonZeroU32, NonZeroU64};
13
14#[inline(always)]
15pub fn try_u32_from_bytes(bytes: &[u8]) -> Result<NonZeroU32, Error> {
16 unsafe {
17 match bytes.len() {
18 1 => helpers::make_u32_bytes(bytes, 1, 0x80),
19 2 => helpers::make_u32_bytes(bytes, 2, 0x8080),
20 3 => helpers::make_u32_bytes(bytes, 3, 0x0080_8080),
21 4 => helpers::make_u32_bytes(bytes, 4, 0x8080_8080),
22 _ => Err(Error::InvalidSize),
23 }
24 }
25}
26
27#[test]
28fn test_u32_from_bytes() {
29 assert_eq!(
30 NonZeroU32::new(if cfg!(target_endian = "little") {
31 0x6262_6161
32 } else {
33 0x6161_6262
34 })
35 .unwrap(),
36 try_u32_from_bytes(b"aabb").unwrap()
37 );
38}
39
40#[inline(always)]
41pub fn try_u64_from_bytes(bytes: &[u8]) -> Result<NonZeroU64, Error> {
42 let len = bytes.len();
43 if !(1..=8).contains(&len) {
44 return Err(Error::InvalidSize);
45 }
46 let mask = 0x8080_8080_8080_8080_u64 >> (8 * (8 - len));
47 unsafe { helpers::make_u64_bytes(bytes, len, mask) }
48}
49
50#[test]
51fn test_u64_from_bytes() {
52 assert_eq!(
53 NonZeroU64::new(if cfg!(target_endian = "little") {
54 0x6262_6262_6161_6161
55 } else {
56 0x6161_6161_6262_6262
57 })
58 .unwrap(),
59 try_u64_from_bytes(b"aaaabbbb").unwrap()
60 );
61}
62
63#[inline(always)]
64pub fn try_u128_from_bytes(bytes: &[u8]) -> Result<NonZeroU128, Error> {
65 let len = bytes.len();
66 if !(1..=16).contains(&len) {
67 return Err(Error::InvalidSize);
68 }
69 let mask = 0x8080_8080_8080_8080_8080_8080_8080_8080_u128 >> (8 * (16 - len));
70 unsafe { helpers::make_u128_bytes(bytes, len, mask) }
71}
72
73#[test]
74fn test_u128_from_bytes() {
75 assert_eq!(
76 NonZeroU128::new(if cfg!(target_endian = "little") {
77 0x6262_6262_6262_6262_6161_6161_6161_6161
78 } else {
79 0x6161_6161_6161_6161_6262_6262_6262_6262
80 })
81 .unwrap(),
82 try_u128_from_bytes(b"aaaaaaaabbbbbbbb").unwrap()
83 );
84}