1use core::convert::TryFrom;
17use core::ops::{
18 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
19 Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
20};
21
22use crate::error::{DivError, OverflowError};
23
24macro_rules! construct_smallint {
25 ($ty:ident, $inner:ident, $to:ident, $into:ident, $bits:literal, $max:expr, $doc:meta) => {
26 #[$doc]
27 #[derive(PartialEq, Eq, Debug, Copy, Clone, Default, PartialOrd, Ord, Hash)]
28 #[cfg_attr(
29 feature = "serde",
30 derive(Serialize, Deserialize),
31 serde(crate = "serde_crate", transparent)
32 )]
33 #[allow(non_camel_case_types)]
34 pub struct $ty($inner);
35
36 impl $ty {
37 pub const BITS: u32 = $bits;
39
40 pub const MIN: Self = Self(0);
42
43 pub const MAX: Self = Self($max);
45
46 pub const ONE: Self = Self(1);
48
49 pub const ZERO: Self = Self(0);
51
52 pub const fn with(value: $inner) -> Self {
56 assert!(value <= $max, "provided value exceeds Self::MAX");
57 Self(value)
58 }
59
60 pub const fn $to(&self) -> $inner {
62 self.0 as $inner
63 }
64
65 pub const fn $into(self) -> $inner {
67 self.0 as $inner
68 }
69 }
70
71 impl ::core::convert::TryFrom<$inner> for $ty {
72 type Error = OverflowError<$inner>;
73 #[inline]
74 fn try_from(value: $inner) -> Result<Self, Self::Error> {
75 if value > $max {
76 Err(OverflowError { max: $max, value })
77 } else {
78 Ok(Self(value))
79 }
80 }
81 }
82
83 impl From<$ty> for $inner {
84 #[inline]
85 fn from(val: $ty) -> Self {
86 val.0
87 }
88 }
89
90 impl AsRef<$inner> for $ty {
91 #[inline]
92 fn as_ref(&self) -> &$inner {
93 &self.0
94 }
95 }
96
97 impl ::core::str::FromStr for $ty {
98 type Err = ::core::num::ParseIntError;
99 #[inline]
100 fn from_str(s: &str) -> Result<Self, Self::Err> {
101 Self::try_from($inner::from_str(s)?).map_err(|_| u8::from_str("257").unwrap_err())
102 }
103 }
104
105 impl ::core::fmt::Display for $ty {
106 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
107 self.0.fmt(f)
108 }
109 }
110
111 impl core::fmt::UpperHex for $ty {
112 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
113 core::fmt::UpperHex::fmt(&self.as_ref(), f)
114 }
115 }
116
117 impl core::fmt::LowerHex for $ty {
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
119 core::fmt::LowerHex::fmt(&self.as_ref(), f)
120 }
121 }
122
123 impl core::fmt::Octal for $ty {
124 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
125 core::fmt::Octal::fmt(&self.as_ref(), f)
126 }
127 }
128
129 impl core::fmt::Binary for $ty {
130 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
131 core::fmt::Binary::fmt(&self.as_ref(), f)
132 }
133 }
134
135 impl_op!($ty, $inner, Add, add, AddAssign, add_assign, +);
136 impl_op!($ty, $inner, Sub, sub, SubAssign, sub_assign, -);
137 impl_op!($ty, $inner, Mul, mul, MulAssign, mul_assign, *);
138 impl_op!($ty, $inner, Div, div, DivAssign, div_assign, /);
139 impl_op!($ty, $inner, Rem, rem, RemAssign, rem_assign, %);
140 impl_op!($ty, $inner, BitAnd, bitand, BitAndAssign, bitand_assign, &);
141 impl_op!($ty, $inner, BitOr, bitor, BitOrAssign, bitor_assign, |);
142 impl_op!($ty, $inner, BitXor, bitxor, BitXorAssign, bitxor_assign, ^);
143 impl_op!($ty, $inner, Shl, shl, ShlAssign, shl_assign, <<);
144 impl_op!($ty, $inner, Shr, shr, ShrAssign, shr_assign, >>);
145
146 impl $ty {
147 pub fn checked_add<T>(self, rhs: T) -> Option<Self> where T: Into<$inner> {
150 self.0.checked_add(rhs.into()).and_then(|val| Self::try_from(val).ok())
151 }
152 pub fn saturating_add<T>(self, rhs: T) -> Self where T: Into<$inner> {
155 let res = self.0.saturating_add(rhs.into());
156 if res > Self::MAX.$to() {
157 Self::MAX
158 } else {
159 Self(res)
160 }
161 }
162 pub fn overflowing_add<T>(self, rhs: T) -> (Self, bool) where T: Into<$inner> {
168 let mut ret = self.0.overflowing_add(rhs.into());
169 if ret.0 > Self::MAX.0 {
170 ret.0 %= Self::MAX.0;
171 ret.1 = true;
172 }
173 (Self(ret.0), ret.1)
174 }
175 pub fn wrapping_add<T>(self, rhs: T) -> Self where T: Into<$inner> {
178 #[allow(clippy::modulo_one)]
179 Self(self.0.wrapping_add(rhs.into()) % Self::MAX.0)
180 }
181
182 pub fn checked_sub<T>(self, rhs: T) -> Option<Self> where T: Into<$inner> {
185 self.0.checked_sub(rhs.into()).and_then(|val| Self::try_from(val).ok())
186 }
187 pub fn saturating_sub<T>(self, rhs: T) -> Self where T: Into<$inner> {
190 let res = self.0.saturating_sub(rhs.into());
191 if res > Self::MAX.$to() {
192 Self::MAX
193 } else {
194 Self(res)
195 }
196 }
197 pub fn overflowing_sub<T>(self, rhs: T) -> (Self, bool) where T: Into<$inner> {
203 let mut ret = self.0.overflowing_sub(rhs.into());
204 if ret.0 > Self::MAX.0 {
205 ret.0 %= Self::MAX.0;
206 ret.1 = true;
207 }
208 (Self(ret.0), ret.1)
209 }
210 pub fn wrapping_sub<T>(self, rhs: T) -> Self where T: Into<$inner> {
213 #[allow(clippy::modulo_one)]
214 Self(self.0.wrapping_sub(rhs.into()) % Self::MAX.0)
215 }
216
217 pub fn checked_mul<T>(self, rhs: T) -> Option<Self> where T: Into<$inner> {
220 self.0.checked_mul(rhs.into()).and_then(|val| Self::try_from(val).ok())
221 }
222 pub fn saturating_mul<T>(self, rhs: T) -> Self where T: Into<$inner> {
225 let res = self.0.saturating_mul(rhs.into());
226 if res > Self::MAX.0 {
227 Self::MAX
228 } else {
229 Self(res)
230 }
231 }
232 pub fn overflowing_mul<T>(self, rhs: T) -> (Self, bool) where T: Into<$inner> {
238 let mut ret = self.0.overflowing_mul(rhs.into());
239 if ret.0 > Self::MAX.0 {
240 ret.0 %= Self::MAX.0;
241 ret.1 = true;
242 }
243 (Self(ret.0), ret.1)
244 }
245 pub fn wrapping_mul<T>(self, rhs: T) -> Self where T: Into<$inner> {
248 #[allow(clippy::modulo_one)]
249 Self(self.0.wrapping_mul(rhs.into()) % Self::MAX.0)
250 }
251
252 #[inline]
253 pub fn div_rem(self, other: Self) -> Result<(Self, Self), DivError> {
254 if other == Self(0) {
256 return Err(DivError::ZeroDiv)
257 }
258 let quotient = self / other;
259 Ok((quotient, self - (quotient * other)))
260 }
261 }
262 };
263}
264macro_rules! impl_op {
265 ($ty:ty, $inner:ty, $op:ident, $fn:ident, $op_assign:ident, $fn_assign:ident, $sign:tt) => {
266 impl<T> $op<T> for $ty where T: Into<$inner> {
267 type Output = $ty;
268 #[inline]
269 fn $fn(self, rhs: T) -> Self::Output {
270 Self::try_from((self.0).$fn(rhs.into())).expect(stringify!(
271 "attempt to ",
272 $fn,
273 " with overflow"
274 ))
275 }
276 }
277 impl<T> $op<T> for &$ty where T: Into<$inner> {
278 type Output = $ty;
279 #[inline]
280 fn $fn(self, rhs: T) -> Self::Output {
281 *self $sign rhs
282 }
283 }
284
285 impl<T> $op_assign<T> for $ty where T: Into<$inner> {
286 #[inline]
287 fn $fn_assign(&mut self, rhs: T) {
288 self.0 = (*self $sign rhs).0
289 }
290 }
291 };
292}
293
294construct_smallint!(
295 u1,
296 u8,
297 to_u8,
298 into_u8,
299 1,
300 1,
301 doc = "1-bit unsigned integer in the range `0..1`. It can be used instead of `bool` when \
302 1-bit numeric (and not boolean) arithmetic is required"
303);
304construct_smallint!(
305 u2,
306 u8,
307 to_u8,
308 into_u8,
309 2,
310 3,
311 doc = "2-bit unsigned integer in the range `0..4`"
312);
313construct_smallint!(
314 u3,
315 u8,
316 to_u8,
317 into_u8,
318 3,
319 7,
320 doc = "3-bit unsigned integer in the range `0..8`"
321);
322construct_smallint!(
323 u4,
324 u8,
325 to_u8,
326 into_u8,
327 4,
328 15,
329 doc = "4-bit unsigned integer in the range `0..16`"
330);
331construct_smallint!(
332 u5,
333 u8,
334 to_u8,
335 into_u8,
336 5,
337 31,
338 doc = "5-bit unsigned integer in the range `0..32`"
339);
340construct_smallint!(
341 u6,
342 u8,
343 to_u8,
344 into_u8,
345 6,
346 63,
347 doc = "6-bit unsigned integer in the range `0..64`"
348);
349construct_smallint!(
350 u7,
351 u8,
352 to_u8,
353 into_u8,
354 7,
355 127,
356 doc = "7-bit unsigned integer in the range `0..128`"
357);
358construct_smallint!(
359 u24,
360 u32,
361 to_u32,
362 into_u32,
363 24,
364 0xFF_FF_FF,
365 doc = "24-bit unsigned integer in the range `0..16_777_216`"
366);
367construct_smallint!(
368 u40,
369 u64,
370 to_u64,
371 into_u64,
372 40,
373 0xFF_FFFF_FFFF,
374 doc = "40-bit unsigned integer in the range `0..2^40`"
375);
376construct_smallint!(
377 u48,
378 u64,
379 to_u64,
380 into_u64,
381 48,
382 0xFFFF_FFFF_FFFF,
383 doc = "48-bit unsigned integer in the range `0..2^48`"
384);
385construct_smallint!(
386 u56,
387 u64,
388 to_u64,
389 into_u64,
390 56,
391 0xFF_FFFF_FFFF_FFFF,
392 doc = "56-bit unsigned integer in the range `0..2^56`"
393);
394
395impl From<u1> for u2 {
396 fn from(value: u1) -> Self { Self(value.0) }
397}
398
399impl From<u1> for u3 {
400 fn from(value: u1) -> Self { Self(value.0) }
401}
402
403impl From<u2> for u3 {
404 fn from(value: u2) -> Self { Self(value.0) }
405}
406
407impl From<u1> for u4 {
408 fn from(value: u1) -> Self { Self(value.0) }
409}
410
411impl From<u2> for u4 {
412 fn from(value: u2) -> Self { Self(value.0) }
413}
414
415impl From<u3> for u4 {
416 fn from(value: u3) -> Self { Self(value.0) }
417}
418
419impl From<u1> for u5 {
420 fn from(value: u1) -> Self { Self(value.0) }
421}
422
423impl From<u2> for u5 {
424 fn from(value: u2) -> Self { Self(value.0) }
425}
426
427impl From<u3> for u5 {
428 fn from(value: u3) -> Self { Self(value.0) }
429}
430
431impl From<u4> for u5 {
432 fn from(value: u4) -> Self { Self(value.0) }
433}
434
435impl From<u1> for u6 {
436 fn from(value: u1) -> Self { Self(value.0) }
437}
438
439impl From<u2> for u6 {
440 fn from(value: u2) -> Self { Self(value.0) }
441}
442
443impl From<u3> for u6 {
444 fn from(value: u3) -> Self { Self(value.0) }
445}
446
447impl From<u4> for u6 {
448 fn from(value: u4) -> Self { Self(value.0) }
449}
450
451impl From<u5> for u6 {
452 fn from(value: u5) -> Self { Self(value.0) }
453}
454
455impl From<u1> for u7 {
456 fn from(value: u1) -> Self { Self(value.0) }
457}
458
459impl From<u2> for u7 {
460 fn from(value: u2) -> Self { Self(value.0) }
461}
462
463impl From<u3> for u7 {
464 fn from(value: u3) -> Self { Self(value.0) }
465}
466
467impl From<u4> for u7 {
468 fn from(value: u4) -> Self { Self(value.0) }
469}
470
471impl From<u5> for u7 {
472 fn from(value: u5) -> Self { Self(value.0) }
473}
474
475impl From<u6> for u7 {
476 fn from(value: u6) -> Self { Self(value.0) }
477}
478
479impl From<u24> for i32 {
480 fn from(val: u24) -> Self { val.0 as i32 }
481}
482
483impl From<u24> for i64 {
484 fn from(val: u24) -> Self { val.0 as i64 }
485}
486
487impl From<u24> for i128 {
488 fn from(val: u24) -> Self { val.0 as i128 }
489}
490
491impl From<u24> for isize {
492 fn from(val: u24) -> Self { val.0 as isize }
493}
494
495impl From<u24> for u64 {
496 fn from(val: u24) -> Self { val.0 as u64 }
497}
498
499impl From<u24> for u128 {
500 fn from(val: u24) -> Self { val.0 as u128 }
501}
502
503impl From<u24> for usize {
504 fn from(val: u24) -> Self { val.0 as usize }
505}
506
507impl From<u48> for i64 {
508 fn from(val: u48) -> Self { val.0 as i64 }
509}
510
511impl From<u40> for i128 {
512 fn from(val: u40) -> Self { val.0 as i128 }
513}
514
515impl From<u40> for isize {
516 fn from(val: u40) -> Self { val.0 as isize }
517}
518
519impl From<u40> for u128 {
520 fn from(val: u40) -> Self { val.0 as u128 }
521}
522
523impl From<u40> for usize {
524 fn from(val: u40) -> Self { val.0 as usize }
525}
526
527impl From<u48> for i128 {
528 fn from(val: u48) -> Self { val.0 as i128 }
529}
530
531impl From<u48> for isize {
532 fn from(val: u48) -> Self { val.0 as isize }
533}
534
535impl From<u48> for u128 {
536 fn from(val: u48) -> Self { val.0 as u128 }
537}
538
539impl From<u48> for usize {
540 fn from(val: u48) -> Self { val.0 as usize }
541}
542
543impl From<u56> for i64 {
544 fn from(val: u56) -> Self { val.0 as i64 }
545}
546
547impl From<u56> for i128 {
548 fn from(val: u56) -> Self { val.0 as i128 }
549}
550
551impl From<u56> for isize {
552 fn from(val: u56) -> Self { val.0 as isize }
553}
554
555impl From<u56> for u128 {
556 fn from(val: u56) -> Self { val.0 as u128 }
557}
558
559impl From<u56> for usize {
560 fn from(val: u56) -> Self { val.0 as usize }
561}
562
563impl u24 {
564 pub fn from_le_bytes(bytes: [u8; 3]) -> Self {
567 let mut inner = [0u8; 4];
568 inner[..3].copy_from_slice(&bytes);
569 Self(u32::from_le_bytes(inner))
570 }
571
572 pub fn to_le_bytes(self) -> [u8; 3] {
575 let mut inner = [0u8; 3];
576 inner.copy_from_slice(&self.0.to_le_bytes()[..3]);
577 inner
578 }
579
580 pub fn from_be_bytes(bytes: [u8; 3]) -> Self {
583 let mut inner = [0u8; 4];
584 inner[1..].copy_from_slice(&bytes);
585 Self(u32::from_be_bytes(inner))
586 }
587
588 pub fn to_be_bytes(self) -> [u8; 3] {
591 let mut inner = [0u8; 3];
592 inner.copy_from_slice(&self.0.to_be_bytes()[1..]);
593 inner
594 }
595
596 pub const fn to_i32(&self) -> i32 { self.0 as i32 }
598
599 pub const fn to_i64(&self) -> i64 { self.0 as i64 }
601
602 pub const fn to_i128(&self) -> i128 { self.0 as i128 }
604
605 pub const fn to_isize(&self) -> isize { self.0 as isize }
607
608 pub const fn to_u64(&self) -> u64 { self.0 as u64 }
610
611 pub const fn to_u128(&self) -> u128 { self.0 as u128 }
613
614 pub const fn to_usize(&self) -> usize { self.0 as usize }
616
617 pub const fn into_i32(self) -> i32 { self.0 as i32 }
619
620 pub const fn into_i64(self) -> i64 { self.0 as i64 }
622
623 pub const fn into_i128(self) -> i128 { self.0 as i128 }
625
626 pub const fn into_isize(self) -> isize { self.0 as isize }
628
629 pub const fn into_u64(self) -> u64 { self.0 as u64 }
631
632 pub const fn into_u128(self) -> u128 { self.0 as u128 }
634
635 pub const fn into_usize(self) -> usize { self.0 as usize }
637}
638
639macro_rules! impl_subu64 {
640 ($ty:ty, $len:literal) => {
641 impl $ty {
642 pub fn from_le_bytes(bytes: [u8; $len]) -> Self {
645 let mut inner = [0u8; 8];
646 inner[..$len].copy_from_slice(&bytes);
647 Self(u64::from_le_bytes(inner))
648 }
649
650 pub fn to_le_bytes(self) -> [u8; $len] {
653 let mut inner = [0u8; $len];
654 inner.copy_from_slice(&self.0.to_le_bytes()[..$len]);
655 inner
656 }
657
658 pub fn from_be_bytes(bytes: [u8; $len]) -> Self {
661 let mut inner = [0u8; 8];
662 inner[(8 - $len)..].copy_from_slice(&bytes);
663 Self(u64::from_be_bytes(inner))
664 }
665
666 pub fn to_be_bytes(self) -> [u8; $len] {
669 let mut inner = [0u8; $len];
670 inner.copy_from_slice(&self.0.to_be_bytes()[(8 - $len)..]);
671 inner
672 }
673
674 pub const fn to_i64(&self) -> i64 { self.0 as i64 }
676
677 pub const fn to_i128(&self) -> i128 { self.0 as i128 }
679
680 pub const fn to_isize(&self) -> isize { self.0 as isize }
682
683 pub const fn to_u128(&self) -> u128 { self.0 as u128 }
685
686 pub const fn to_usize(&self) -> usize { self.0 as usize }
688
689 pub const fn into_i64(self) -> i64 { self.0 as i64 }
691
692 pub const fn into_i128(self) -> i128 { self.0 as i128 }
694
695 pub const fn into_isize(self) -> isize { self.0 as isize }
697
698 pub const fn into_u128(self) -> u128 { self.0 as u128 }
700
701 pub const fn into_usize(self) -> usize { self.0 as usize }
703 }
704 };
705}
706impl_subu64!(u40, 5);
707impl_subu64!(u48, 6);
708impl_subu64!(u56, 7);
709
710#[cfg(test)]
711mod test {
712 use super::*;
713
714 #[test]
715 fn ubit_test() {
716 let mut u_1 = u1::try_from(u1::MAX.to_u8()).unwrap();
717 let mut u_2 = u2::try_from(u2::MAX.to_u8()).unwrap();
718 let mut u_3 = u3::try_from(u3::MAX.to_u8()).unwrap();
719 let mut u_4 = u4::try_from(u4::MAX.to_u8()).unwrap();
720 let mut u_5 = u5::try_from(u5::MAX.to_u8()).unwrap();
721 let mut u_6 = u6::try_from(u6::MAX.to_u8()).unwrap();
722 let mut u_7 = u7::try_from(u7::MAX.to_u8()).unwrap();
723 let mut u_24 = u24::try_from(u24::MAX.to_u32()).unwrap();
724
725 assert_eq!(u_1, u1::with(1));
726 assert_eq!(u_2, u2::with(3));
727 assert_eq!(u_3, u3::with(7));
728 assert_eq!(u_4, u4::with(15));
729 assert_eq!(u_5, u5::with(31));
730 assert_eq!(u_6, u6::with(63));
731 assert_eq!(u_7, u7::with(127));
732
733 assert_eq!(u_1.to_u8(), 1u8);
734 assert_eq!(u_2.to_u8(), 3u8);
735 assert_eq!(u_3.to_u8(), 7u8);
736 assert_eq!(u_4.to_u8(), 15u8);
737 assert_eq!(u_5.to_u8(), 31u8);
738 assert_eq!(u_6.to_u8(), 63u8);
739 assert_eq!(u_7.to_u8(), 127u8);
740 assert_eq!(u_24.to_u32(), (1 << 24) - 1);
741
742 u_1 -= 1;
743 u_2 -= 1;
744 u_3 -= 1;
745 u_4 -= 1;
746 u_5 -= 1;
747 u_6 -= 1;
748 u_7 -= 1;
749 u_24 -= 1u32;
750
751 assert_eq!(u_1.to_u8(), 0u8);
752 assert_eq!(u_2.to_u8(), 2u8);
753 assert_eq!(u_3.to_u8(), 6u8);
754 assert_eq!(u_4.to_u8(), 14u8);
755 assert_eq!(u_5.to_u8(), 30u8);
756 assert_eq!(u_6.to_u8(), 62u8);
757 assert_eq!(u_7.to_u8(), 126u8);
758 assert_eq!(u_24.to_u32(), (1 << 24) - 2);
759
760 u_1 /= 2;
761 u_1 *= 2;
762 u_1 += 1;
763
764 u_2 /= 2;
765 u_2 *= 2;
766 u_2 += 1;
767
768 u_3 /= 2;
769 u_3 *= 2;
770 u_3 += 1;
771
772 u_4 /= 2;
773 u_4 *= 2;
774 u_4 += 1;
775
776 u_5 /= 2;
777 u_5 *= 2;
778 u_5 += 1;
779
780 u_6 /= 2;
781 u_6 *= 2;
782 u_6 += 1;
783
784 u_7 /= 2;
785 u_7 *= 2;
786 u_7 += 1;
787
788 u_24 /= 2u32;
789 u_24 *= 2u32;
790 u_24 += 1u32;
791
792 assert_eq!(u_1.to_u8(), 1u8);
793 assert_eq!(u_2.to_u8(), 3u8);
794 assert_eq!(u_3.to_u8(), 7u8);
795 assert_eq!(u_4.to_u8(), 15u8);
796 assert_eq!(u_5.to_u8(), 31u8);
797 assert_eq!(u_6.to_u8(), 63u8);
798 assert_eq!(u_7.to_u8(), 127u8);
799 assert_eq!(u_24.to_u32(), (1 << 24) - 1);
800
801 assert_eq!(u_1.to_u8() % 2, 1);
802 assert_eq!(u_2.to_u8() % 2, 1);
803 assert_eq!(u_3.to_u8() % 2, 1);
804 assert_eq!(u_4.to_u8() % 2, 1);
805 assert_eq!(u_5.to_u8() % 2, 1);
806 assert_eq!(u_6.to_u8() % 2, 1);
807 assert_eq!(u_7.to_u8() % 2, 1);
808 assert_eq!(u_24.to_u32() % 2, 1);
809 }
810
811 #[test]
812 #[should_panic(expected = "OverflowError { max: 1, value: 2 }")]
813 fn u1_overflow_test() { u1::try_from(2).unwrap(); }
814
815 #[test]
816 #[should_panic(expected = "OverflowError { max: 3, value: 4 }")]
817 fn u2_overflow_test() { u2::try_from(4).unwrap(); }
818
819 #[test]
820 #[should_panic(expected = "OverflowError { max: 7, value: 8 }")]
821 fn u3_overflow_test() { u3::try_from(8).unwrap(); }
822
823 #[test]
824 #[should_panic(expected = "OverflowError { max: 15, value: 16 }")]
825 fn u4_overflow_test() { u4::try_from(16).unwrap(); }
826
827 #[test]
828 #[should_panic(expected = "OverflowError { max: 31, value: 32 }")]
829 fn u5_overflow_test() { u5::try_from(32).unwrap(); }
830
831 #[test]
832 #[should_panic(expected = "OverflowError { max: 63, value: 64 }")]
833 fn u6_overflow_test() { u6::try_from(64).unwrap(); }
834
835 #[test]
836 #[should_panic(expected = "OverflowError { max: 127, value: 128 }")]
837 fn u7_overflow_test() { u7::try_from(128).unwrap(); }
838
839 #[test]
840 #[should_panic(expected = "OverflowError { max: 16777215, value: 16777216 }")]
841 fn u24_overflow_test() { u24::try_from(1 << 24).unwrap(); }
842
843 #[test]
844 fn u24_endianess() {
845 let val: u32 = 0x00adbeef;
846 let le = [0xef, 0xbe, 0xad];
847 let v1 = u24::with(val);
848 assert_eq!(v1.to_u32(), val);
849 assert_eq!(v1.to_le_bytes(), le);
850 let v2 = u24::from_le_bytes(le);
851 assert_eq!(v2.to_le_bytes(), le);
852 assert_eq!(v2, v1);
853 assert_eq!(v2.to_u32(), v1.to_u32());
854 }
855
856 #[test]
857 fn smallint_div_rem_0() {
858 let u_2 = u2::MAX;
859 let u_2_2 = u2::try_from(2).unwrap();
860 let u_2_half = (u2::MAX / 2, u2::MAX % 2);
861 let u_2_zero = u2::ZERO;
862
863 assert_eq!(u2::div_rem(u_2, u_2_2), Ok(u_2_half));
864 assert_eq!(u2::div_rem(u_2, u_2_zero), Err(DivError::ZeroDiv));
865 }
866
867 #[test]
868 fn smallint_div_rem() {
869 let u_2 = u2::MAX;
870 let u_2_zero = u2::ZERO;
871 assert_eq!(u2::div_rem(u_2, u_2_zero), Err(DivError::ZeroDiv));
872 }
873
874 #[test]
875 fn fmt_test() {
876 let u_1 = u1::MAX;
877 let u_2 = u2::MAX;
878 let u_3 = u3::MAX;
879 let u_4 = u4::MAX;
880 let u_5 = u5::MAX;
881 let u_6 = u6::MAX;
882 let u_7 = u7::MAX;
883 let u_24 = u24::MAX;
884
885 assert_eq!(format!("{:X}", u_1), "1");
887 assert_eq!(format!("{:X}", u_2), "3");
888 assert_eq!(format!("{:X}", u_3), "7");
889 assert_eq!(format!("{:X}", u_4), "F");
890 assert_eq!(format!("{:X}", u_5), "1F");
891 assert_eq!(format!("{:X}", u_6), "3F");
892 assert_eq!(format!("{:X}", u_7), "7F");
893 assert_eq!(format!("{:X}", u_24), "FFFFFF");
894 assert_eq!(format!("{:#X}", u_1), "0x1");
895 assert_eq!(format!("{:#X}", u_2), "0x3");
896 assert_eq!(format!("{:#X}", u_3), "0x7");
897 assert_eq!(format!("{:#X}", u_4), "0xF");
898 assert_eq!(format!("{:#X}", u_5), "0x1F");
899 assert_eq!(format!("{:#X}", u_6), "0x3F");
900 assert_eq!(format!("{:#X}", u_7), "0x7F");
901 assert_eq!(format!("{:#X}", u_24), "0xFFFFFF");
902
903 assert_eq!(format!("{:x}", u_1), "1");
905 assert_eq!(format!("{:x}", u_2), "3");
906 assert_eq!(format!("{:x}", u_3), "7");
907 assert_eq!(format!("{:x}", u_4), "f");
908 assert_eq!(format!("{:x}", u_5), "1f");
909 assert_eq!(format!("{:x}", u_6), "3f");
910 assert_eq!(format!("{:x}", u_7), "7f");
911 assert_eq!(format!("{:x}", u_24), "ffffff");
912 assert_eq!(format!("{:#x}", u_1), "0x1");
913 assert_eq!(format!("{:#x}", u_2), "0x3");
914 assert_eq!(format!("{:#x}", u_3), "0x7");
915 assert_eq!(format!("{:#x}", u_4), "0xf");
916 assert_eq!(format!("{:#x}", u_5), "0x1f");
917 assert_eq!(format!("{:#x}", u_6), "0x3f");
918 assert_eq!(format!("{:#x}", u_7), "0x7f");
919 assert_eq!(format!("{:#x}", u_24), "0xffffff");
920
921 assert_eq!(format!("{:o}", u_1), "1");
923 assert_eq!(format!("{:o}", u_2), "3");
924 assert_eq!(format!("{:o}", u_3), "7");
925 assert_eq!(format!("{:o}", u_4), "17");
926 assert_eq!(format!("{:o}", u_5), "37");
927 assert_eq!(format!("{:o}", u_6), "77");
928 assert_eq!(format!("{:o}", u_7), "177");
929 assert_eq!(format!("{:o}", u_24), "77777777");
930 assert_eq!(format!("{:#o}", u_1), "0o1");
931 assert_eq!(format!("{:#o}", u_2), "0o3");
932 assert_eq!(format!("{:#o}", u_3), "0o7");
933 assert_eq!(format!("{:#o}", u_4), "0o17");
934 assert_eq!(format!("{:#o}", u_5), "0o37");
935 assert_eq!(format!("{:#o}", u_6), "0o77");
936 assert_eq!(format!("{:#o}", u_7), "0o177");
937 assert_eq!(format!("{:#o}", u_24), "0o77777777");
938
939 assert_eq!(format!("{:b}", u_1), "1");
941 assert_eq!(format!("{:b}", u_2), "11");
942 assert_eq!(format!("{:b}", u_3), "111");
943 assert_eq!(format!("{:b}", u_4), "1111");
944 assert_eq!(format!("{:b}", u_5), "11111");
945 assert_eq!(format!("{:b}", u_6), "111111");
946 assert_eq!(format!("{:b}", u_7), "1111111");
947 assert_eq!(format!("{:b}", u_24), "111111111111111111111111");
948 assert_eq!(format!("{:#b}", u_1), "0b1");
949 assert_eq!(format!("{:#b}", u_2), "0b11");
950 assert_eq!(format!("{:#b}", u_3), "0b111");
951 assert_eq!(format!("{:#b}", u_4), "0b1111");
952 assert_eq!(format!("{:#b}", u_5), "0b11111");
953 assert_eq!(format!("{:#b}", u_6), "0b111111");
954 assert_eq!(format!("{:#b}", u_7), "0b1111111");
955 assert_eq!(format!("{:#b}", u_24), "0b111111111111111111111111");
956 }
957}