musli_common/int/
traits.rs1use core::ops::{BitAnd, BitXor, Neg, Shl, Shr};
2
3use musli::Context;
4
5use crate::options::ByteOrder;
6use crate::reader::Reader;
7use crate::writer::Writer;
8
9pub trait Unsigned:
11 Copy
12 + Shr<u32, Output = Self>
13 + Shl<u32, Output = Self>
14 + BitXor<Output = Self>
15 + BitAnd<Output = Self>
16 + Ord
17{
18 const ONE: Self;
20
21 const BYTES: u8;
23
24 const BITS: u32;
26
27 type Signed: Signed<Unsigned = Self>;
29
30 fn signed(self) -> Self::Signed;
32
33 fn from_byte(byte: u8) -> Self;
35
36 fn as_byte(self) -> u8;
38
39 fn is_smaller_than(self, byte: u8) -> bool;
41
42 fn is_zero(self) -> bool;
44
45 fn checked_shr(self, value: u32) -> Option<Self>;
47
48 fn checked_shl(self, value: u32) -> Option<Self>;
50
51 fn wrapping_shl(self, value: u32) -> Self;
53
54 fn checked_add(self, value: Self) -> Option<Self>;
56
57 fn wrapping_add(self, value: Self) -> Self;
59}
60
61pub trait UnsignedOps: Unsigned {
63 fn write_bytes<C, W>(self, cx: &C, writer: W, byte_order: ByteOrder) -> Result<(), C::Error>
66 where
67 C: ?Sized + Context,
68 W: Writer;
69
70 fn read_bytes<'de, C, R>(cx: &C, reader: R, byte_order: ByteOrder) -> Result<Self, C::Error>
72 where
73 C: ?Sized + Context,
74 R: Reader<'de>;
75}
76
77pub trait Signed:
79 Copy
80 + Neg<Output = Self>
81 + Shr<u32, Output = Self>
82 + Shl<u32, Output = Self>
83 + BitXor<Output = Self>
84{
85 const BITS: u32;
87
88 type Unsigned: Unsigned<Signed = Self>;
90
91 fn unsigned(self) -> Self::Unsigned;
93}
94
95macro_rules! implement {
96 ($signed:ty, $unsigned:ty) => {
97 impl Signed for $signed {
98 const BITS: u32 = <$signed>::BITS;
99
100 type Unsigned = $unsigned;
101
102 fn unsigned(self) -> Self::Unsigned {
103 self as $unsigned
104 }
105 }
106
107 impl Unsigned for $unsigned {
108 const ONE: Self = 1;
109 const BYTES: u8 = (<$unsigned>::BITS / 8) as u8;
110 const BITS: u32 = <$signed>::BITS;
111
112 type Signed = $signed;
113
114 #[inline]
115 fn signed(self) -> Self::Signed {
116 self as $signed
117 }
118
119 #[inline]
120 fn from_byte(byte: u8) -> Self {
121 byte as $unsigned
122 }
123
124 #[inline]
125 fn as_byte(self) -> u8 {
126 self as u8
127 }
128
129 #[inline]
130 fn is_smaller_than(self, b: u8) -> bool {
131 self < b as $unsigned
132 }
133
134 #[inline]
135 fn is_zero(self) -> bool {
136 self == 0
137 }
138
139 #[inline]
140 fn checked_shr(self, value: u32) -> Option<Self> {
141 self.checked_shr(value)
142 }
143
144 #[inline]
145 fn checked_shl(self, value: u32) -> Option<Self> {
146 self.checked_shl(value)
147 }
148
149 #[inline]
150 fn wrapping_shl(self, value: u32) -> Self {
151 self.wrapping_shl(value)
152 }
153
154 #[inline]
155 fn checked_add(self, value: Self) -> Option<Self> {
156 self.checked_add(value)
157 }
158
159 #[inline]
160 fn wrapping_add(self, value: Self) -> Self {
161 self.wrapping_add(value)
162 }
163 }
164 };
165}
166
167macro_rules! implement_ops {
168 ($signed:ty, $unsigned:ty) => {
169 implement!($signed, $unsigned);
170
171 impl UnsignedOps for $unsigned {
172 #[inline(always)]
173 fn write_bytes<C, W>(
174 self,
175 cx: &C,
176 mut writer: W,
177 byte_order: ByteOrder,
178 ) -> Result<(), C::Error>
179 where
180 C: ?Sized + Context,
181 W: Writer,
182 {
183 let bytes = match byte_order {
184 ByteOrder::NATIVE => self,
185 _ => <$unsigned>::swap_bytes(self),
186 };
187
188 let bytes = <$unsigned>::to_ne_bytes(bytes);
189 writer.write_bytes(cx, &bytes)
190 }
191
192 #[inline(always)]
193 fn read_bytes<'de, C, R>(
194 cx: &C,
195 mut reader: R,
196 byte_order: ByteOrder,
197 ) -> Result<Self, C::Error>
198 where
199 C: ?Sized + Context,
200 R: Reader<'de>,
201 {
202 let bytes = reader.read_array(cx)?;
203 let bytes = <$unsigned>::from_ne_bytes(bytes);
204
205 let bytes = match byte_order {
206 ByteOrder::NATIVE => bytes,
207 _ => <$unsigned>::swap_bytes(bytes),
208 };
209
210 Ok(bytes)
211 }
212 }
213 };
214}
215
216implement_ops!(i8, u8);
217implement_ops!(i16, u16);
218implement_ops!(i32, u32);
219implement_ops!(i64, u64);
220implement_ops!(i128, u128);
221implement!(isize, usize);