1use core::{convert::Infallible, fmt};
4
5use super::FixedCodec;
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub struct U24RangeError {
10 value: u32,
11}
12
13impl U24RangeError {
14 #[must_use]
16 pub const fn new(value: u32) -> Self {
17 Self { value }
18 }
19
20 #[must_use]
22 pub const fn value(&self) -> u32 {
23 self.value
24 }
25}
26
27impl fmt::Display for U24RangeError {
28 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
29 write!(
30 formatter,
31 "{} does not fit in an unsigned 24-bit integer",
32 self.value
33 )
34 }
35}
36
37impl core::error::Error for U24RangeError {}
38
39macro_rules! fixed_integer_codec {
40 ($name:ident, $value:ty, $width:literal, $from:ident, $to:ident) => {
41 impl FixedCodec for $name {
42 type Value<'wire>
43 = $value
44 where
45 Self: 'wire;
46 type EncodeError = Infallible;
47 type Plan<'value>
48 = [u8; $width]
49 where
50 Self: 'value;
51
52 const WIDTH: usize = $width;
53
54 #[inline]
55 fn decode<'wire>(bytes: &'wire [u8]) -> Self::Value<'wire> {
56 let mut encoded = [0_u8; $width];
57 encoded.copy_from_slice(bytes);
58 <$value>::$from(encoded)
59 }
60
61 #[inline]
62 fn plan<'value>(
63 value: Self::Value<'value>,
64 ) -> Result<Self::Plan<'value>, Self::EncodeError> {
65 Ok(value.$to())
66 }
67 }
68 };
69}
70
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
73pub struct U8;
74fixed_integer_codec!(U8, u8, 1, from_ne_bytes, to_ne_bytes);
75
76#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
78pub struct I8;
79fixed_integer_codec!(I8, i8, 1, from_ne_bytes, to_ne_bytes);
80
81#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
83pub struct BeU16;
84fixed_integer_codec!(BeU16, u16, 2, from_be_bytes, to_be_bytes);
85
86#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
88pub struct LeU16;
89fixed_integer_codec!(LeU16, u16, 2, from_le_bytes, to_le_bytes);
90
91#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
93pub struct BeI16;
94fixed_integer_codec!(BeI16, i16, 2, from_be_bytes, to_be_bytes);
95
96#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
98pub struct LeI16;
99fixed_integer_codec!(LeI16, i16, 2, from_le_bytes, to_le_bytes);
100
101#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
103pub struct BeU32;
104fixed_integer_codec!(BeU32, u32, 4, from_be_bytes, to_be_bytes);
105
106#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
108pub struct LeU32;
109fixed_integer_codec!(LeU32, u32, 4, from_le_bytes, to_le_bytes);
110
111#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
113pub struct BeI32;
114fixed_integer_codec!(BeI32, i32, 4, from_be_bytes, to_be_bytes);
115
116#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
118pub struct LeI32;
119fixed_integer_codec!(LeI32, i32, 4, from_le_bytes, to_le_bytes);
120
121#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
123pub struct BeU64;
124fixed_integer_codec!(BeU64, u64, 8, from_be_bytes, to_be_bytes);
125
126#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
128pub struct LeU64;
129fixed_integer_codec!(LeU64, u64, 8, from_le_bytes, to_le_bytes);
130
131#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
133pub struct BeI64;
134fixed_integer_codec!(BeI64, i64, 8, from_be_bytes, to_be_bytes);
135
136#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
138pub struct LeI64;
139fixed_integer_codec!(LeI64, i64, 8, from_le_bytes, to_le_bytes);
140
141#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
143pub struct BeU128;
144fixed_integer_codec!(BeU128, u128, 16, from_be_bytes, to_be_bytes);
145
146#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
148pub struct LeU128;
149fixed_integer_codec!(LeU128, u128, 16, from_le_bytes, to_le_bytes);
150
151#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
153pub struct BeI128;
154fixed_integer_codec!(BeI128, i128, 16, from_be_bytes, to_be_bytes);
155
156#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
158pub struct LeI128;
159fixed_integer_codec!(LeI128, i128, 16, from_le_bytes, to_le_bytes);
160
161#[inline]
162fn decode_be_u24(bytes: [u8; 3]) -> u32 {
163 u32::from_be_bytes([0, bytes[0], bytes[1], bytes[2]])
164}
165
166#[inline]
167fn decode_le_u24(bytes: [u8; 3]) -> u32 {
168 u32::from_le_bytes([bytes[0], bytes[1], bytes[2], 0])
169}
170
171#[inline]
172fn encode_be_u24(value: u32) -> [u8; 3] {
173 let bytes = value.to_be_bytes();
174 [bytes[1], bytes[2], bytes[3]]
175}
176
177#[inline]
178fn encode_le_u24(value: u32) -> [u8; 3] {
179 let bytes = value.to_le_bytes();
180 [bytes[0], bytes[1], bytes[2]]
181}
182
183#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
185pub struct BeU24;
186
187impl FixedCodec for BeU24 {
188 type Value<'wire>
189 = u32
190 where
191 Self: 'wire;
192 type EncodeError = U24RangeError;
193 type Plan<'value>
194 = [u8; 3]
195 where
196 Self: 'value;
197
198 const WIDTH: usize = 3;
199
200 #[inline]
201 fn decode<'wire>(bytes: &'wire [u8]) -> Self::Value<'wire> {
202 let mut encoded = [0_u8; 3];
203 encoded.copy_from_slice(bytes);
204 decode_be_u24(encoded)
205 }
206
207 #[inline]
208 fn plan<'value>(value: Self::Value<'value>) -> Result<Self::Plan<'value>, Self::EncodeError> {
209 if value > 0x00ff_ffff {
210 Err(U24RangeError::new(value))
211 } else {
212 Ok(encode_be_u24(value))
213 }
214 }
215}
216
217#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
219pub struct LeU24;
220
221impl FixedCodec for LeU24 {
222 type Value<'wire>
223 = u32
224 where
225 Self: 'wire;
226 type EncodeError = U24RangeError;
227 type Plan<'value>
228 = [u8; 3]
229 where
230 Self: 'value;
231
232 const WIDTH: usize = 3;
233
234 #[inline]
235 fn decode<'wire>(bytes: &'wire [u8]) -> Self::Value<'wire> {
236 let mut encoded = [0_u8; 3];
237 encoded.copy_from_slice(bytes);
238 decode_le_u24(encoded)
239 }
240
241 #[inline]
242 fn plan<'value>(value: Self::Value<'value>) -> Result<Self::Plan<'value>, Self::EncodeError> {
243 if value > 0x00ff_ffff {
244 Err(U24RangeError::new(value))
245 } else {
246 Ok(encode_le_u24(value))
247 }
248 }
249}