packed_char/u22.rs
1use core::{
2 borrow::Borrow,
3 fmt::{self, Display, Formatter},
4 ops::Deref,
5};
6
7/// A 22-bit unsigned integer.
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct U22(u32);
10
11impl Display for U22 {
12 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
13 write!(f, "{}", self.0)
14 }
15}
16
17impl U22 {
18 /// The largest value that can be expressed by this type
19 pub const MAX: u32 = !(u32::MAX << 22);
20
21 /// Creates a new 22-bit integer from the given 32-bit integer if it is small enough to fit.
22 ///
23 /// # Examples
24 ///
25 /// ```
26 /// # use packed_char::{U22, U22FromU32Error};
27 /// assert_eq!(U22::from_u32(42).map(U22::as_u32), Ok(42));
28 /// assert_eq!(U22::from_u32(U22::MAX).map(U22::as_u32), Ok(U22::MAX));
29 /// assert_eq!(U22::from_u32(U22::MAX + 1), Err(U22FromU32Error(U22::MAX + 1)));
30 /// ```
31 pub const fn from_u32(n: u32) -> Result<Self, U22FromU32Error> {
32 if n > Self::MAX {
33 Err(U22FromU32Error(n))
34 } else {
35 Ok(Self(n))
36 }
37 }
38
39 /// Creates a new 22-bit integer from the given 32-bit integer.
40 ///
41 /// # Safety
42 ///
43 /// The provided integer must be no greater than [`U22::MAX`].
44 ///
45 /// # Examples
46 ///
47 /// ```
48 /// # use packed_char::U22;
49 /// let u22 = unsafe { U22::from_u32_unchecked(42) };
50 /// assert_eq!(u22.as_u32(), 42);
51 /// ```
52 pub const unsafe fn from_u32_unchecked(n: u32) -> Self {
53 Self(n)
54 }
55
56 /// Gets the 22-bit integer as a 32-bit integer.
57 ///
58 /// # Examples
59 ///
60 /// ```
61 /// # use packed_char::U22;
62 /// let u22 = U22::from_u32(42).unwrap();
63 /// assert_eq!(u22.as_ref(), &42);
64 /// ```
65 pub const fn as_u32(self) -> u32 {
66 self.0
67 }
68}
69
70impl TryFrom<u32> for U22 {
71 type Error = U22FromU32Error;
72
73 fn try_from(n: u32) -> Result<Self, Self::Error> {
74 Self::from_u32(n)
75 }
76}
77
78impl From<U22> for u32 {
79 fn from(u22: U22) -> Self {
80 u22.0
81 }
82}
83
84impl AsRef<u32> for U22 {
85 fn as_ref(&self) -> &u32 {
86 &self.0
87 }
88}
89
90impl Borrow<u32> for U22 {
91 fn borrow(&self) -> &u32 {
92 &self.0
93 }
94}
95
96impl Deref for U22 {
97 type Target = u32;
98
99 fn deref(&self) -> &Self::Target {
100 &self.0
101 }
102}
103
104// TODO: Implement core::error::Error when stabilized
105
106/// Error type for 32-bit to 22-bit integer conversion.
107#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
108pub struct U22FromU32Error(
109 /// The `u32` that failed to be converted to a [`U22`].
110 pub u32,
111);
112
113impl Display for U22FromU32Error {
114 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
115 write!(f, "{} exceeds U22::MAX", self.0)
116 }
117}