1use core::convert::TryFrom;
23use core::ops::{
24 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
25 Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
26};
27
28use crate::error::{DivError, OverflowError};
29
30macro_rules! construct_smallint {
31 ($ty:ident, $inner:ident, $to:ident, $into:ident, $bits:literal, $max:expr, $doc:meta) => {
32 #[$doc]
33 #[derive(PartialEq, Eq, Debug, Copy, Clone, Default, PartialOrd, Ord, Hash)]
34 #[cfg_attr(
35 feature = "serde",
36 derive(Serialize, Deserialize),
37 serde(crate = "serde_crate", transparent)
38 )]
39 #[allow(non_camel_case_types)]
40 pub struct $ty($inner);
41
42 impl $ty {
43 pub const BITS: u32 = $bits;
45
46 pub const MIN: Self = Self(0);
48
49 pub const MAX: Self = Self($max);
51
52 pub const ONE: Self = Self(1);
54
55 pub const ZERO: Self = Self(0);
57
58 pub const fn with(value: $inner) -> Self {
62 assert!(value <= $max, "provided value exceeds Self::MAX");
63 Self(value)
64 }
65
66 pub const fn $to(&self) -> $inner {
68 self.0 as $inner
69 }
70
71 pub const fn $into(self) -> $inner {
73 self.0 as $inner
74 }
75 }
76
77 impl ::core::convert::TryFrom<$inner> for $ty {
78 type Error = OverflowError<$inner>;
79 #[inline]
80 fn try_from(value: $inner) -> Result<Self, Self::Error> {
81 if value > $max {
82 Err(OverflowError { max: $max, value })
83 } else {
84 Ok(Self(value))
85 }
86 }
87 }
88
89 impl From<$ty> for $inner {
90 #[inline]
91 fn from(val: $ty) -> Self {
92 val.0
93 }
94 }
95
96 impl AsRef<$inner> for $ty {
97 #[inline]
98 fn as_ref(&self) -> &$inner {
99 &self.0
100 }
101 }
102
103 impl ::core::str::FromStr for $ty {
104 type Err = ::core::num::ParseIntError;
105 #[inline]
106 fn from_str(s: &str) -> Result<Self, Self::Err> {
107 Self::try_from($inner::from_str(s)?).map_err(|_| u8::from_str("257").unwrap_err())
108 }
109 }
110
111 impl ::core::fmt::Display for $ty {
112 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
113 self.0.fmt(f)
114 }
115 }
116
117 impl core::fmt::UpperHex for $ty {
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
119 core::fmt::UpperHex::fmt(&self.as_ref(), f)
120 }
121 }
122
123 impl core::fmt::LowerHex for $ty {
124 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
125 core::fmt::LowerHex::fmt(&self.as_ref(), f)
126 }
127 }
128
129 impl core::fmt::Octal for $ty {
130 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
131 core::fmt::Octal::fmt(&self.as_ref(), f)
132 }
133 }
134
135 impl core::fmt::Binary for $ty {
136 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
137 core::fmt::Binary::fmt(&self.as_ref(), f)
138 }
139 }
140
141 impl_op!($ty, $inner, Add, add, AddAssign, add_assign, +);
142 impl_op!($ty, $inner, Sub, sub, SubAssign, sub_assign, -);
143 impl_op!($ty, $inner, Mul, mul, MulAssign, mul_assign, *);
144 impl_op!($ty, $inner, Div, div, DivAssign, div_assign, /);
145 impl_op!($ty, $inner, Rem, rem, RemAssign, rem_assign, %);
146 impl_op!($ty, $inner, BitAnd, bitand, BitAndAssign, bitand_assign, &);
147 impl_op!($ty, $inner, BitOr, bitor, BitOrAssign, bitor_assign, |);
148 impl_op!($ty, $inner, BitXor, bitxor, BitXorAssign, bitxor_assign, ^);
149 impl_op!($ty, $inner, Shl, shl, ShlAssign, shl_assign, <<);
150 impl_op!($ty, $inner, Shr, shr, ShrAssign, shr_assign, >>);
151
152 impl $ty {
153 pub fn checked_add<T>(self, rhs: T) -> Option<Self> where T: Into<$inner> {
156 self.0.checked_add(rhs.into()).and_then(|val| Self::try_from(val).ok())
157 }
158 pub fn saturating_add<T>(self, rhs: T) -> Self where T: Into<$inner> {
161 let res = self.0.saturating_add(rhs.into());
162 if res > Self::MAX.$to() {
163 Self::MAX
164 } else {
165 Self(res)
166 }
167 }
168 pub fn overflowing_add<T>(self, rhs: T) -> (Self, bool) where T: Into<$inner> {
174 let mut ret = self.0.overflowing_add(rhs.into());
175 if ret.0 > Self::MAX.0 {
176 ret.0 %= Self::MAX.0;
177 ret.1 = true;
178 }
179 (Self(ret.0), ret.1)
180 }
181 pub fn wrapping_add<T>(self, rhs: T) -> Self where T: Into<$inner> {
184 #[allow(clippy::modulo_one)]
185 Self(self.0.wrapping_add(rhs.into()) % Self::MAX.0)
186 }
187
188 pub fn checked_sub<T>(self, rhs: T) -> Option<Self> where T: Into<$inner> {
191 self.0.checked_sub(rhs.into()).and_then(|val| Self::try_from(val).ok())
192 }
193 pub fn saturating_sub<T>(self, rhs: T) -> Self where T: Into<$inner> {
196 let res = self.0.saturating_sub(rhs.into());
197 if res > Self::MAX.$to() {
198 Self::MAX
199 } else {
200 Self(res)
201 }
202 }
203 pub fn overflowing_sub<T>(self, rhs: T) -> (Self, bool) where T: Into<$inner> {
209 let mut ret = self.0.overflowing_sub(rhs.into());
210 if ret.0 > Self::MAX.0 {
211 ret.0 %= Self::MAX.0;
212 ret.1 = true;
213 }
214 (Self(ret.0), ret.1)
215 }
216 pub fn wrapping_sub<T>(self, rhs: T) -> Self where T: Into<$inner> {
219 #[allow(clippy::modulo_one)]
220 Self(self.0.wrapping_sub(rhs.into()) % Self::MAX.0)
221 }
222
223 pub fn checked_mul<T>(self, rhs: T) -> Option<Self> where T: Into<$inner> {
226 self.0.checked_mul(rhs.into()).and_then(|val| Self::try_from(val).ok())
227 }
228 pub fn saturating_mul<T>(self, rhs: T) -> Self where T: Into<$inner> {
231 let res = self.0.saturating_mul(rhs.into());
232 if res > Self::MAX.0 {
233 Self::MAX
234 } else {
235 Self(res)
236 }
237 }
238 pub fn overflowing_mul<T>(self, rhs: T) -> (Self, bool) where T: Into<$inner> {
244 let mut ret = self.0.overflowing_mul(rhs.into());
245 if ret.0 > Self::MAX.0 {
246 ret.0 %= Self::MAX.0;
247 ret.1 = true;
248 }
249 (Self(ret.0), ret.1)
250 }
251 pub fn wrapping_mul<T>(self, rhs: T) -> Self where T: Into<$inner> {
254 #[allow(clippy::modulo_one)]
255 Self(self.0.wrapping_mul(rhs.into()) % Self::MAX.0)
256 }
257
258 #[inline]
259 pub fn div_rem(self, other: Self) -> Result<(Self, Self), DivError> {
260 if other == Self(0) {
262 return Err(DivError::ZeroDiv)
263 }
264 let quotient = self / other;
265 Ok((quotient, self - (quotient * other)))
266 }
267 }
268 };
269}
270macro_rules! impl_op {
271 ($ty:ty, $inner:ty, $op:ident, $fn:ident, $op_assign:ident, $fn_assign:ident, $sign:tt) => {
272 impl<T> $op<T> for $ty where T: Into<$inner> {
273 type Output = $ty;
274 #[inline]
275 fn $fn(self, rhs: T) -> Self::Output {
276 Self::try_from((self.0).$fn(rhs.into())).expect(stringify!(
277 "attempt to ",
278 $fn,
279 " with overflow"
280 ))
281 }
282 }
283 impl<T> $op<T> for &$ty where T: Into<$inner> {
284 type Output = $ty;
285 #[inline]
286 fn $fn(self, rhs: T) -> Self::Output {
287 *self $sign rhs
288 }
289 }
290
291 impl<T> $op_assign<T> for $ty where T: Into<$inner> {
292 #[inline]
293 fn $fn_assign(&mut self, rhs: T) {
294 self.0 = (*self $sign rhs).0
295 }
296 }
297 };
298}
299
300construct_smallint!(
301 u1,
302 u8,
303 to_u8,
304 into_u8,
305 1,
306 1,
307 doc = "1-bit unsigned integer in the range `0..=1`. It can be used instead of `bool` when \
308 1-bit numeric (and not boolean) arithmetic is required"
309);
310construct_smallint!(
311 u2,
312 u8,
313 to_u8,
314 into_u8,
315 2,
316 3,
317 doc = "2-bit unsigned integer in the range `0..=3`"
318);
319construct_smallint!(
320 u3,
321 u8,
322 to_u8,
323 into_u8,
324 3,
325 7,
326 doc = "3-bit unsigned integer in the range `0..=7`"
327);
328construct_smallint!(
329 u4,
330 u8,
331 to_u8,
332 into_u8,
333 4,
334 15,
335 doc = "4-bit unsigned integer in the range `0..=15`"
336);
337construct_smallint!(
338 u5,
339 u8,
340 to_u8,
341 into_u8,
342 5,
343 31,
344 doc = "5-bit unsigned integer in the range `0..=31`"
345);
346construct_smallint!(
347 u6,
348 u8,
349 to_u8,
350 into_u8,
351 6,
352 63,
353 doc = "6-bit unsigned integer in the range `0..=63`"
354);
355construct_smallint!(
356 u7,
357 u8,
358 to_u8,
359 into_u8,
360 7,
361 127,
362 doc = "7-bit unsigned integer in the range `0..=127`"
363);
364construct_smallint!(
365 u10,
366 u16,
367 to_u16,
368 into_u16,
369 10,
370 0x3_FF,
371 doc = "10-bit unsigned integer in the range `0..=1023`"
372);
373construct_smallint!(
374 u12,
375 u16,
376 to_u16,
377 into_u16,
378 12,
379 0xF_FF,
380 doc = "12-bit unsigned integer in the range `0..=4095`"
381);
382construct_smallint!(
383 u14,
384 u16,
385 to_u16,
386 into_u16,
387 14,
388 0x3F_FF,
389 doc = "14-bit unsigned integer in the range `0..=16383`"
390);
391construct_smallint!(
392 u20,
393 u32,
394 to_u32,
395 into_u32,
396 20,
397 0xF_FF_FF,
398 doc = "20-bit unsigned integer in the range `0..=1_048_575`"
399);
400construct_smallint!(
401 u24,
402 u32,
403 to_u32,
404 into_u32,
405 24,
406 0xFF_FF_FF,
407 doc = "24-bit unsigned integer in the range `0..=16_777_215`"
408);
409construct_smallint!(
410 u40,
411 u64,
412 to_u64,
413 into_u64,
414 40,
415 0xFF_FFFF_FFFF,
416 doc = "40-bit unsigned integer in the range `0..2^40`"
417);
418construct_smallint!(
419 u48,
420 u64,
421 to_u64,
422 into_u64,
423 48,
424 0xFFFF_FFFF_FFFF,
425 doc = "48-bit unsigned integer in the range `0..2^48`"
426);
427construct_smallint!(
428 u56,
429 u64,
430 to_u64,
431 into_u64,
432 56,
433 0xFF_FFFF_FFFF_FFFF,
434 doc = "56-bit unsigned integer in the range `0..2^56`"
435);
436
437impl From<u1> for u2 {
438 fn from(value: u1) -> Self { Self(value.0) }
439}
440
441impl From<u1> for u3 {
442 fn from(value: u1) -> Self { Self(value.0) }
443}
444
445impl From<u2> for u3 {
446 fn from(value: u2) -> Self { Self(value.0) }
447}
448
449impl From<u1> for u4 {
450 fn from(value: u1) -> Self { Self(value.0) }
451}
452
453impl From<u2> for u4 {
454 fn from(value: u2) -> Self { Self(value.0) }
455}
456
457impl From<u3> for u4 {
458 fn from(value: u3) -> Self { Self(value.0) }
459}
460
461impl From<u1> for u5 {
462 fn from(value: u1) -> Self { Self(value.0) }
463}
464
465impl From<u2> for u5 {
466 fn from(value: u2) -> Self { Self(value.0) }
467}
468
469impl From<u3> for u5 {
470 fn from(value: u3) -> Self { Self(value.0) }
471}
472
473impl From<u4> for u5 {
474 fn from(value: u4) -> Self { Self(value.0) }
475}
476
477impl From<u1> for u6 {
478 fn from(value: u1) -> Self { Self(value.0) }
479}
480
481impl From<u2> for u6 {
482 fn from(value: u2) -> Self { Self(value.0) }
483}
484
485impl From<u3> for u6 {
486 fn from(value: u3) -> Self { Self(value.0) }
487}
488
489impl From<u4> for u6 {
490 fn from(value: u4) -> Self { Self(value.0) }
491}
492
493impl From<u5> for u6 {
494 fn from(value: u5) -> Self { Self(value.0) }
495}
496
497impl From<u1> for u7 {
498 fn from(value: u1) -> Self { Self(value.0) }
499}
500
501impl From<u2> for u7 {
502 fn from(value: u2) -> Self { Self(value.0) }
503}
504
505impl From<u3> for u7 {
506 fn from(value: u3) -> Self { Self(value.0) }
507}
508
509impl From<u4> for u7 {
510 fn from(value: u4) -> Self { Self(value.0) }
511}
512
513impl From<u5> for u7 {
514 fn from(value: u5) -> Self { Self(value.0) }
515}
516
517impl From<u6> for u7 {
518 fn from(value: u6) -> Self { Self(value.0) }
519}
520
521impl From<u10> for i32 {
522 fn from(val: u10) -> Self { val.0 as i32 }
523}
524
525impl From<u10> for i64 {
526 fn from(val: u10) -> Self { val.0 as i64 }
527}
528
529impl From<u10> for i128 {
530 fn from(val: u10) -> Self { val.0 as i128 }
531}
532
533impl From<u10> for isize {
534 fn from(val: u10) -> Self { val.0 as isize }
535}
536
537impl From<u10> for u64 {
538 fn from(val: u10) -> Self { val.0 as u64 }
539}
540
541impl From<u10> for u128 {
542 fn from(val: u10) -> Self { val.0 as u128 }
543}
544
545impl From<u10> for usize {
546 fn from(val: u10) -> Self { val.0 as usize }
547}
548
549impl From<u12> for i32 {
550 fn from(val: u12) -> Self { val.0 as i32 }
551}
552
553impl From<u12> for i64 {
554 fn from(val: u12) -> Self { val.0 as i64 }
555}
556
557impl From<u12> for i128 {
558 fn from(val: u12) -> Self { val.0 as i128 }
559}
560
561impl From<u12> for isize {
562 fn from(val: u12) -> Self { val.0 as isize }
563}
564
565impl From<u12> for u64 {
566 fn from(val: u12) -> Self { val.0 as u64 }
567}
568
569impl From<u12> for u128 {
570 fn from(val: u12) -> Self { val.0 as u128 }
571}
572
573impl From<u12> for usize {
574 fn from(val: u12) -> Self { val.0 as usize }
575}
576
577impl From<u14> for i32 {
578 fn from(val: u14) -> Self { val.0 as i32 }
579}
580
581impl From<u14> for i64 {
582 fn from(val: u14) -> Self { val.0 as i64 }
583}
584
585impl From<u14> for i128 {
586 fn from(val: u14) -> Self { val.0 as i128 }
587}
588
589impl From<u14> for isize {
590 fn from(val: u14) -> Self { val.0 as isize }
591}
592
593impl From<u14> for u64 {
594 fn from(val: u14) -> Self { val.0 as u64 }
595}
596
597impl From<u14> for u128 {
598 fn from(val: u14) -> Self { val.0 as u128 }
599}
600
601impl From<u14> for usize {
602 fn from(val: u14) -> Self { val.0 as usize }
603}
604
605impl From<u20> for i32 {
606 fn from(val: u20) -> Self { val.0 as i32 }
607}
608
609impl From<u20> for i64 {
610 fn from(val: u20) -> Self { val.0 as i64 }
611}
612
613impl From<u20> for i128 {
614 fn from(val: u20) -> Self { val.0 as i128 }
615}
616
617impl From<u20> for isize {
618 fn from(val: u20) -> Self { val.0 as isize }
619}
620
621impl From<u20> for u64 {
622 fn from(val: u20) -> Self { val.0 as u64 }
623}
624
625impl From<u20> for u128 {
626 fn from(val: u20) -> Self { val.0 as u128 }
627}
628
629impl From<u20> for usize {
630 fn from(val: u20) -> Self { val.0 as usize }
631}
632
633impl From<u24> for i32 {
634 fn from(val: u24) -> Self { val.0 as i32 }
635}
636
637impl From<u24> for i64 {
638 fn from(val: u24) -> Self { val.0 as i64 }
639}
640
641impl From<u24> for i128 {
642 fn from(val: u24) -> Self { val.0 as i128 }
643}
644
645impl From<u24> for isize {
646 fn from(val: u24) -> Self { val.0 as isize }
647}
648
649impl From<u24> for u64 {
650 fn from(val: u24) -> Self { val.0 as u64 }
651}
652
653impl From<u24> for u128 {
654 fn from(val: u24) -> Self { val.0 as u128 }
655}
656
657impl From<u24> for usize {
658 fn from(val: u24) -> Self { val.0 as usize }
659}
660
661impl From<u48> for i64 {
662 fn from(val: u48) -> Self { val.0 as i64 }
663}
664
665impl From<u40> for i128 {
666 fn from(val: u40) -> Self { val.0 as i128 }
667}
668
669impl From<u40> for isize {
670 fn from(val: u40) -> Self { val.0 as isize }
671}
672
673impl From<u40> for u128 {
674 fn from(val: u40) -> Self { val.0 as u128 }
675}
676
677impl From<u40> for usize {
678 fn from(val: u40) -> Self { val.0 as usize }
679}
680
681impl From<u48> for i128 {
682 fn from(val: u48) -> Self { val.0 as i128 }
683}
684
685impl From<u48> for isize {
686 fn from(val: u48) -> Self { val.0 as isize }
687}
688
689impl From<u48> for u128 {
690 fn from(val: u48) -> Self { val.0 as u128 }
691}
692
693impl From<u48> for usize {
694 fn from(val: u48) -> Self { val.0 as usize }
695}
696
697impl From<u56> for i64 {
698 fn from(val: u56) -> Self { val.0 as i64 }
699}
700
701impl From<u56> for i128 {
702 fn from(val: u56) -> Self { val.0 as i128 }
703}
704
705impl From<u56> for isize {
706 fn from(val: u56) -> Self { val.0 as isize }
707}
708
709impl From<u56> for u128 {
710 fn from(val: u56) -> Self { val.0 as u128 }
711}
712
713impl From<u56> for usize {
714 fn from(val: u56) -> Self { val.0 as usize }
715}
716
717impl u24 {
718 pub fn from_le_bytes(bytes: [u8; 3]) -> Self {
721 let mut inner = [0u8; 4];
722 inner[..3].copy_from_slice(&bytes);
723 Self(u32::from_le_bytes(inner))
724 }
725
726 pub fn to_le_bytes(self) -> [u8; 3] {
729 let mut inner = [0u8; 3];
730 inner.copy_from_slice(&self.0.to_le_bytes()[..3]);
731 inner
732 }
733
734 pub fn from_be_bytes(bytes: [u8; 3]) -> Self {
737 let mut inner = [0u8; 4];
738 inner[1..].copy_from_slice(&bytes);
739 Self(u32::from_be_bytes(inner))
740 }
741
742 pub fn to_be_bytes(self) -> [u8; 3] {
745 let mut inner = [0u8; 3];
746 inner.copy_from_slice(&self.0.to_be_bytes()[1..]);
747 inner
748 }
749
750 pub const fn to_i32(&self) -> i32 { self.0 as i32 }
752
753 pub const fn to_i64(&self) -> i64 { self.0 as i64 }
755
756 pub const fn to_i128(&self) -> i128 { self.0 as i128 }
758
759 pub const fn to_isize(&self) -> isize { self.0 as isize }
761
762 pub const fn to_u64(&self) -> u64 { self.0 as u64 }
764
765 pub const fn to_u128(&self) -> u128 { self.0 as u128 }
767
768 pub const fn to_usize(&self) -> usize { self.0 as usize }
770
771 pub const fn into_i32(self) -> i32 { self.0 as i32 }
773
774 pub const fn into_i64(self) -> i64 { self.0 as i64 }
776
777 pub const fn into_i128(self) -> i128 { self.0 as i128 }
779
780 pub const fn into_isize(self) -> isize { self.0 as isize }
782
783 pub const fn into_u64(self) -> u64 { self.0 as u64 }
785
786 pub const fn into_u128(self) -> u128 { self.0 as u128 }
788
789 pub const fn into_usize(self) -> usize { self.0 as usize }
791}
792
793macro_rules! impl_subu64 {
794 ($ty:ty, $len:literal) => {
795 impl $ty {
796 pub fn from_le_bytes(bytes: [u8; $len]) -> Self {
799 let mut inner = [0u8; 8];
800 inner[..$len].copy_from_slice(&bytes);
801 Self(u64::from_le_bytes(inner))
802 }
803
804 pub fn to_le_bytes(self) -> [u8; $len] {
807 let mut inner = [0u8; $len];
808 inner.copy_from_slice(&self.0.to_le_bytes()[..$len]);
809 inner
810 }
811
812 pub fn from_be_bytes(bytes: [u8; $len]) -> Self {
815 let mut inner = [0u8; 8];
816 inner[(8 - $len)..].copy_from_slice(&bytes);
817 Self(u64::from_be_bytes(inner))
818 }
819
820 pub fn to_be_bytes(self) -> [u8; $len] {
823 let mut inner = [0u8; $len];
824 inner.copy_from_slice(&self.0.to_be_bytes()[(8 - $len)..]);
825 inner
826 }
827
828 pub const fn to_i64(&self) -> i64 { self.0 as i64 }
830
831 pub const fn to_i128(&self) -> i128 { self.0 as i128 }
833
834 pub const fn to_isize(&self) -> isize { self.0 as isize }
836
837 pub const fn to_u128(&self) -> u128 { self.0 as u128 }
839
840 pub const fn to_usize(&self) -> usize { self.0 as usize }
842
843 pub const fn into_i64(self) -> i64 { self.0 as i64 }
845
846 pub const fn into_i128(self) -> i128 { self.0 as i128 }
848
849 pub const fn into_isize(self) -> isize { self.0 as isize }
851
852 pub const fn into_u128(self) -> u128 { self.0 as u128 }
854
855 pub const fn into_usize(self) -> usize { self.0 as usize }
857 }
858 };
859}
860impl_subu64!(u40, 5);
861impl_subu64!(u48, 6);
862impl_subu64!(u56, 7);
863
864#[cfg(test)]
865mod test {
866 use super::*;
867
868 #[test]
869 fn ubit_test() {
870 let mut u_1 = u1::try_from(u1::MAX.to_u8()).unwrap();
871 let mut u_2 = u2::try_from(u2::MAX.to_u8()).unwrap();
872 let mut u_3 = u3::try_from(u3::MAX.to_u8()).unwrap();
873 let mut u_4 = u4::try_from(u4::MAX.to_u8()).unwrap();
874 let mut u_5 = u5::try_from(u5::MAX.to_u8()).unwrap();
875 let mut u_6 = u6::try_from(u6::MAX.to_u8()).unwrap();
876 let mut u_7 = u7::try_from(u7::MAX.to_u8()).unwrap();
877 let mut u_10 = u10::try_from(u10::MAX.to_u16()).unwrap();
878 let mut u_12 = u12::try_from(u12::MAX.to_u16()).unwrap();
879 let mut u_14 = u14::try_from(u14::MAX.to_u16()).unwrap();
880 let mut u_20 = u20::try_from(u20::MAX.to_u32()).unwrap();
881 let mut u_24 = u24::try_from(u24::MAX.to_u32()).unwrap();
882
883 assert_eq!(u_1, u1::with(1));
884 assert_eq!(u_2, u2::with(3));
885 assert_eq!(u_3, u3::with(7));
886 assert_eq!(u_4, u4::with(15));
887 assert_eq!(u_5, u5::with(31));
888 assert_eq!(u_6, u6::with(63));
889 assert_eq!(u_7, u7::with(127));
890 assert_eq!(u_10, u10::with(0x3FF));
891 assert_eq!(u_12, u12::with(0xFFF));
892 assert_eq!(u_14, u14::with(0x3FFF));
893 assert_eq!(u_20, u20::with(0xF_FF_FF));
894 assert_eq!(u_24, u24::with(0xFF_FF_FF));
895
896 assert_eq!(u_1.to_u8(), 1u8);
897 assert_eq!(u_2.to_u8(), 3u8);
898 assert_eq!(u_3.to_u8(), 7u8);
899 assert_eq!(u_4.to_u8(), 15u8);
900 assert_eq!(u_5.to_u8(), 31u8);
901 assert_eq!(u_6.to_u8(), 63u8);
902 assert_eq!(u_7.to_u8(), 127u8);
903 assert_eq!(u_10.to_u16(), (1 << 10) - 1);
904 assert_eq!(u_12.to_u16(), (1 << 12) - 1);
905 assert_eq!(u_14.to_u16(), (1 << 14) - 1);
906 assert_eq!(u_20.to_u32(), (1 << 20) - 1);
907 assert_eq!(u_24.to_u32(), (1 << 24) - 1);
908
909 u_1 -= 1;
910 u_2 -= 1;
911 u_3 -= 1;
912 u_4 -= 1;
913 u_5 -= 1;
914 u_6 -= 1;
915 u_7 -= 1;
916 u_10 -= 1u16;
917 u_12 -= 1u16;
918 u_14 -= 1u16;
919 u_20 -= 1u32;
920 u_24 -= 1u32;
921
922 assert_eq!(u_1.to_u8(), 0u8);
923 assert_eq!(u_2.to_u8(), 2u8);
924 assert_eq!(u_3.to_u8(), 6u8);
925 assert_eq!(u_4.to_u8(), 14u8);
926 assert_eq!(u_5.to_u8(), 30u8);
927 assert_eq!(u_6.to_u8(), 62u8);
928 assert_eq!(u_7.to_u8(), 126u8);
929 assert_eq!(u_10.to_u16(), (1 << 10) - 2);
930 assert_eq!(u_12.to_u16(), (1 << 12) - 2);
931 assert_eq!(u_14.to_u16(), (1 << 14) - 2);
932 assert_eq!(u_20.to_u32(), (1 << 20) - 2);
933 assert_eq!(u_24.to_u32(), (1 << 24) - 2);
934
935 u_1 /= 2;
936 u_1 *= 2;
937 u_1 += 1;
938
939 u_2 /= 2;
940 u_2 *= 2;
941 u_2 += 1;
942
943 u_3 /= 2;
944 u_3 *= 2;
945 u_3 += 1;
946
947 u_4 /= 2;
948 u_4 *= 2;
949 u_4 += 1;
950
951 u_5 /= 2;
952 u_5 *= 2;
953 u_5 += 1;
954
955 u_6 /= 2;
956 u_6 *= 2;
957 u_6 += 1;
958
959 u_7 /= 2;
960 u_7 *= 2;
961 u_7 += 1;
962
963 u_10 /= 2u16;
964 u_10 *= 2u16;
965 u_10 += 1u16;
966
967 u_12 /= 2u16;
968 u_12 *= 2u16;
969 u_12 += 1u16;
970
971 u_14 /= 2u16;
972 u_14 *= 2u16;
973 u_14 += 1u16;
974
975 u_20 /= 2u32;
976 u_20 *= 2u32;
977 u_20 += 1u32;
978
979 u_24 /= 2u32;
980 u_24 *= 2u32;
981 u_24 += 1u32;
982
983 assert_eq!(u_1.to_u8(), 1u8);
984 assert_eq!(u_2.to_u8(), 3u8);
985 assert_eq!(u_3.to_u8(), 7u8);
986 assert_eq!(u_4.to_u8(), 15u8);
987 assert_eq!(u_5.to_u8(), 31u8);
988 assert_eq!(u_6.to_u8(), 63u8);
989 assert_eq!(u_7.to_u8(), 127u8);
990 assert_eq!(u_10.to_u16(), (1 << 10) - 1);
991 assert_eq!(u_12.to_u16(), (1 << 12) - 1);
992 assert_eq!(u_14.to_u16(), (1 << 14) - 1);
993 assert_eq!(u_20.to_u32(), (1 << 20) - 1);
994 assert_eq!(u_24.to_u32(), (1 << 24) - 1);
995
996 assert_eq!(u_1.to_u8() % 2, 1);
997 assert_eq!(u_2.to_u8() % 2, 1);
998 assert_eq!(u_3.to_u8() % 2, 1);
999 assert_eq!(u_4.to_u8() % 2, 1);
1000 assert_eq!(u_5.to_u8() % 2, 1);
1001 assert_eq!(u_6.to_u8() % 2, 1);
1002 assert_eq!(u_7.to_u8() % 2, 1);
1003 assert_eq!(u_10.to_u16() % 2, 1);
1004 assert_eq!(u_12.to_u16() % 2, 1);
1005 assert_eq!(u_14.to_u16() % 2, 1);
1006 assert_eq!(u_20.to_u32() % 2, 1);
1007 assert_eq!(u_24.to_u32() % 2, 1);
1008 }
1009
1010 #[test]
1011 #[should_panic(expected = "OverflowError { max: 1, value: 2 }")]
1012 fn u1_overflow_test() { u1::try_from(2).unwrap(); }
1013
1014 #[test]
1015 #[should_panic(expected = "OverflowError { max: 3, value: 4 }")]
1016 fn u2_overflow_test() { u2::try_from(4).unwrap(); }
1017
1018 #[test]
1019 #[should_panic(expected = "OverflowError { max: 7, value: 8 }")]
1020 fn u3_overflow_test() { u3::try_from(8).unwrap(); }
1021
1022 #[test]
1023 #[should_panic(expected = "OverflowError { max: 15, value: 16 }")]
1024 fn u4_overflow_test() { u4::try_from(16).unwrap(); }
1025
1026 #[test]
1027 #[should_panic(expected = "OverflowError { max: 31, value: 32 }")]
1028 fn u5_overflow_test() { u5::try_from(32).unwrap(); }
1029
1030 #[test]
1031 #[should_panic(expected = "OverflowError { max: 63, value: 64 }")]
1032 fn u6_overflow_test() { u6::try_from(64).unwrap(); }
1033
1034 #[test]
1035 #[should_panic(expected = "OverflowError { max: 127, value: 128 }")]
1036 fn u7_overflow_test() { u7::try_from(128).unwrap(); }
1037
1038 #[test]
1039 #[should_panic(expected = "OverflowError { max: 1023, value: 1024 }")]
1040 fn u10_overflow_test() { u10::try_from(1 << 10).unwrap(); }
1041
1042 #[test]
1043 #[should_panic(expected = "OverflowError { max: 4095, value: 4096 }")]
1044 fn u12_overflow_test() { u12::try_from(1 << 12).unwrap(); }
1045
1046 #[test]
1047 #[should_panic(expected = "OverflowError { max: 16383, value: 16384 }")]
1048 fn u14_overflow_test() { u14::try_from(1 << 14).unwrap(); }
1049
1050 #[test]
1051 #[should_panic(expected = "OverflowError { max: 1048575, value: 1048576 }")]
1052 fn u20_overflow_test() { u20::try_from(1 << 20).unwrap(); }
1053
1054 #[test]
1055 #[should_panic(expected = "OverflowError { max: 16777215, value: 16777216 }")]
1056 fn u24_overflow_test() { u24::try_from(1 << 24).unwrap(); }
1057
1058 #[test]
1059 fn u24_endianess() {
1060 let val: u32 = 0x00adbeef;
1061 let le = [0xef, 0xbe, 0xad];
1062 let v1 = u24::with(val);
1063 assert_eq!(v1.to_u32(), val);
1064 assert_eq!(v1.to_le_bytes(), le);
1065 let v2 = u24::from_le_bytes(le);
1066 assert_eq!(v2.to_le_bytes(), le);
1067 assert_eq!(v2, v1);
1068 assert_eq!(v2.to_u32(), v1.to_u32());
1069 }
1070
1071 #[test]
1072 fn smallint_div_rem_0() {
1073 let u_2 = u2::MAX;
1074 let u_2_2 = u2::try_from(2).unwrap();
1075 let u_2_half = (u2::MAX / 2, u2::MAX % 2);
1076 let u_2_zero = u2::ZERO;
1077
1078 assert_eq!(u2::div_rem(u_2, u_2_2), Ok(u_2_half));
1079 assert_eq!(u2::div_rem(u_2, u_2_zero), Err(DivError::ZeroDiv));
1080 }
1081
1082 #[test]
1083 fn smallint_div_rem() {
1084 let u_2 = u2::MAX;
1085 let u_2_zero = u2::ZERO;
1086 assert_eq!(u2::div_rem(u_2, u_2_zero), Err(DivError::ZeroDiv));
1087 }
1088
1089 #[test]
1090 fn fmt_test() {
1091 let u_1 = u1::MAX;
1092 let u_2 = u2::MAX;
1093 let u_3 = u3::MAX;
1094 let u_4 = u4::MAX;
1095 let u_5 = u5::MAX;
1096 let u_6 = u6::MAX;
1097 let u_7 = u7::MAX;
1098 let u_10 = u10::MAX;
1099 let u_12 = u12::MAX;
1100 let u_14 = u14::MAX;
1101 let u_20 = u20::MAX;
1102 let u_24 = u24::MAX;
1103
1104 assert_eq!(format!("{:X}", u_1), "1");
1106 assert_eq!(format!("{:X}", u_2), "3");
1107 assert_eq!(format!("{:X}", u_3), "7");
1108 assert_eq!(format!("{:X}", u_4), "F");
1109 assert_eq!(format!("{:X}", u_5), "1F");
1110 assert_eq!(format!("{:X}", u_6), "3F");
1111 assert_eq!(format!("{:X}", u_7), "7F");
1112 assert_eq!(format!("{:X}", u_10), "3FF");
1113 assert_eq!(format!("{:X}", u_12), "FFF");
1114 assert_eq!(format!("{:X}", u_14), "3FFF");
1115 assert_eq!(format!("{:X}", u_20), "FFFFF");
1116 assert_eq!(format!("{:X}", u_24), "FFFFFF");
1117
1118 assert_eq!(format!("{:#X}", u_1), "0x1");
1119 assert_eq!(format!("{:#X}", u_2), "0x3");
1120 assert_eq!(format!("{:#X}", u_3), "0x7");
1121 assert_eq!(format!("{:#X}", u_4), "0xF");
1122 assert_eq!(format!("{:#X}", u_5), "0x1F");
1123 assert_eq!(format!("{:#X}", u_6), "0x3F");
1124 assert_eq!(format!("{:#X}", u_7), "0x7F");
1125 assert_eq!(format!("{:#X}", u_10), "0x3FF");
1126 assert_eq!(format!("{:#X}", u_12), "0xFFF");
1127 assert_eq!(format!("{:#X}", u_14), "0x3FFF");
1128 assert_eq!(format!("{:#X}", u_20), "0xFFFFF");
1129 assert_eq!(format!("{:#X}", u_24), "0xFFFFFF");
1130
1131 assert_eq!(format!("{:x}", u_1), "1");
1133 assert_eq!(format!("{:x}", u_2), "3");
1134 assert_eq!(format!("{:x}", u_3), "7");
1135 assert_eq!(format!("{:x}", u_4), "f");
1136 assert_eq!(format!("{:x}", u_5), "1f");
1137 assert_eq!(format!("{:x}", u_6), "3f");
1138 assert_eq!(format!("{:x}", u_7), "7f");
1139 assert_eq!(format!("{:x}", u_10), "3ff");
1140 assert_eq!(format!("{:x}", u_12), "fff");
1141 assert_eq!(format!("{:x}", u_14), "3fff");
1142 assert_eq!(format!("{:x}", u_20), "fffff");
1143 assert_eq!(format!("{:x}", u_24), "ffffff");
1144
1145 assert_eq!(format!("{:#x}", u_1), "0x1");
1146 assert_eq!(format!("{:#x}", u_2), "0x3");
1147 assert_eq!(format!("{:#x}", u_3), "0x7");
1148 assert_eq!(format!("{:#x}", u_4), "0xf");
1149 assert_eq!(format!("{:#x}", u_5), "0x1f");
1150 assert_eq!(format!("{:#x}", u_6), "0x3f");
1151 assert_eq!(format!("{:#x}", u_7), "0x7f");
1152 assert_eq!(format!("{:#x}", u_10), "0x3ff");
1153 assert_eq!(format!("{:#x}", u_12), "0xfff");
1154 assert_eq!(format!("{:#x}", u_14), "0x3fff");
1155 assert_eq!(format!("{:#x}", u_20), "0xfffff");
1156 assert_eq!(format!("{:#x}", u_24), "0xffffff");
1157
1158 assert_eq!(format!("{:o}", u_1), "1");
1160 assert_eq!(format!("{:o}", u_2), "3");
1161 assert_eq!(format!("{:o}", u_3), "7");
1162 assert_eq!(format!("{:o}", u_4), "17");
1163 assert_eq!(format!("{:o}", u_5), "37");
1164 assert_eq!(format!("{:o}", u_6), "77");
1165 assert_eq!(format!("{:o}", u_7), "177");
1166 assert_eq!(format!("{:o}", u_10), "1777");
1167 assert_eq!(format!("{:o}", u_12), "7777");
1168 assert_eq!(format!("{:o}", u_14), "37777");
1169 assert_eq!(format!("{:o}", u_20), "3777777");
1170 assert_eq!(format!("{:o}", u_24), "77777777");
1171
1172 assert_eq!(format!("{:#o}", u_1), "0o1");
1173 assert_eq!(format!("{:#o}", u_2), "0o3");
1174 assert_eq!(format!("{:#o}", u_3), "0o7");
1175 assert_eq!(format!("{:#o}", u_4), "0o17");
1176 assert_eq!(format!("{:#o}", u_5), "0o37");
1177 assert_eq!(format!("{:#o}", u_6), "0o77");
1178 assert_eq!(format!("{:#o}", u_7), "0o177");
1179 assert_eq!(format!("{:#o}", u_10), "0o1777");
1180 assert_eq!(format!("{:#o}", u_12), "0o7777");
1181 assert_eq!(format!("{:#o}", u_14), "0o37777");
1182 assert_eq!(format!("{:#o}", u_20), "0o3777777");
1183 assert_eq!(format!("{:#o}", u_24), "0o77777777");
1184
1185 assert_eq!(format!("{:b}", u_1), "1");
1187 assert_eq!(format!("{:b}", u_2), "11");
1188 assert_eq!(format!("{:b}", u_3), "111");
1189 assert_eq!(format!("{:b}", u_4), "1111");
1190 assert_eq!(format!("{:b}", u_5), "11111");
1191 assert_eq!(format!("{:b}", u_6), "111111");
1192 assert_eq!(format!("{:b}", u_7), "1111111");
1193 assert_eq!(format!("{:b}", u_10), "1111111111");
1194 assert_eq!(format!("{:b}", u_12), "111111111111");
1195 assert_eq!(format!("{:b}", u_14), "11111111111111");
1196 assert_eq!(format!("{:b}", u_20), "11111111111111111111");
1197 assert_eq!(format!("{:b}", u_24), "111111111111111111111111");
1198
1199 assert_eq!(format!("{:#b}", u_1), "0b1");
1200 assert_eq!(format!("{:#b}", u_2), "0b11");
1201 assert_eq!(format!("{:#b}", u_3), "0b111");
1202 assert_eq!(format!("{:#b}", u_4), "0b1111");
1203 assert_eq!(format!("{:#b}", u_5), "0b11111");
1204 assert_eq!(format!("{:#b}", u_6), "0b111111");
1205 assert_eq!(format!("{:#b}", u_7), "0b1111111");
1206 assert_eq!(format!("{:#b}", u_10), "0b1111111111");
1207 assert_eq!(format!("{:#b}", u_12), "0b111111111111");
1208 assert_eq!(format!("{:#b}", u_14), "0b11111111111111");
1209 assert_eq!(format!("{:#b}", u_20), "0b11111111111111111111");
1210 assert_eq!(format!("{:#b}", u_24), "0b111111111111111111111111");
1211 }
1212}