1use num_traits::ToPrimitive;
4
5use super::{Encode, Error, Result};
6use crate::{formats::Format, io::IoWrite};
7
8impl<W> Encode<W> for u8
9where
10 W: IoWrite,
11{
12 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
13 match self {
14 0x00..=0x7f => {
15 writer.write(&Format::PositiveFixInt(*self).as_slice())?;
16
17 Ok(1)
18 }
19 _ => {
20 writer.write(&Format::Uint8.as_slice())?;
21 writer.write(&self.to_be_bytes())?;
22 Ok(2)
23 }
24 }
25 }
26}
27
28impl<W> Encode<W> for u128
29where
30 W: IoWrite,
31{
32 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
33 match u64::try_from(*self) {
34 Ok(u64_uint) => u64_uint.encode(writer),
35 Err(_) => Err(Error::InvalidFormat),
36 }
37 }
38}
39
40impl<W> Encode<W> for usize
41where
42 W: IoWrite,
43{
44 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
45 match u64::try_from(*self) {
46 Ok(u64_uint) => u64_uint.encode(writer),
47 Err(_) => Err(Error::InvalidFormat),
48 }
49 }
50}
51
52impl<W> Encode<W> for i8
53where
54 W: IoWrite,
55{
56 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
57 match self {
58 -32..=-1 => {
59 writer.write(&Format::NegativeFixInt(*self).as_slice())?;
60 Ok(1)
61 }
62 _ => {
63 writer.write(&Format::Int8.as_slice())?;
64 writer.write(&self.to_be_bytes())?;
65
66 Ok(2)
67 }
68 }
69 }
70}
71
72impl<W> Encode<W> for isize
73where
74 W: IoWrite,
75{
76 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
77 match i64::try_from(*self) {
78 Ok(i64_int) => i64_int.encode(writer),
79 Err(_) => Err(Error::InvalidFormat),
80 }
81 }
82}
83
84impl<W> Encode<W> for i128
85where
86 W: IoWrite,
87{
88 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
89 match i64::try_from(*self) {
90 Ok(i64_int) => i64_int.encode(writer),
91 Err(_) => Err(Error::InvalidFormat),
92 }
93 }
94}
95
96macro_rules! impl_encode_int {
97 ($ty:ty, $format:expr, $size:expr) => {
98 impl<W> Encode<W> for $ty
99 where
100 W: IoWrite,
101 {
102 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
103 writer.write(&$format.as_slice())?;
104 writer.write(&self.to_be_bytes())?;
105 Ok($size)
106 }
107 }
108 };
109}
110impl_encode_int!(u16, Format::Uint16, 3);
111impl_encode_int!(u32, Format::Uint32, 5);
112impl_encode_int!(u64, Format::Uint64, 9);
113impl_encode_int!(i16, Format::Int16, 3);
114impl_encode_int!(i32, Format::Int32, 5);
115impl_encode_int!(i64, Format::Int64, 9);
116
117macro_rules! impl_nonzero_int {
118 ($ty:ty) => {
119 impl<W> Encode<W> for $ty
120 where
121 W: IoWrite,
122 {
123 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
124 self.get().encode(writer)
125 }
126 }
127 };
128}
129impl_nonzero_int!(core::num::NonZeroU8);
130impl_nonzero_int!(core::num::NonZeroU16);
131impl_nonzero_int!(core::num::NonZeroU32);
132impl_nonzero_int!(core::num::NonZeroU64);
133impl_nonzero_int!(core::num::NonZeroUsize);
134impl_nonzero_int!(core::num::NonZeroI8);
135impl_nonzero_int!(core::num::NonZeroI16);
136impl_nonzero_int!(core::num::NonZeroI32);
137impl_nonzero_int!(core::num::NonZeroI64);
138impl_nonzero_int!(core::num::NonZeroIsize);
139
140macro_rules! impl_atomic_int {
141 ($ty:ty) => {
142 impl<W> Encode<W> for $ty
143 where
144 W: IoWrite,
145 {
146 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
147 self.load(core::sync::atomic::Ordering::Relaxed)
148 .encode(writer)
149 }
150 }
151 };
152}
153impl_atomic_int!(core::sync::atomic::AtomicU8);
154impl_atomic_int!(core::sync::atomic::AtomicU16);
155impl_atomic_int!(core::sync::atomic::AtomicU32);
156impl_atomic_int!(core::sync::atomic::AtomicU64);
157impl_atomic_int!(core::sync::atomic::AtomicUsize);
158impl_atomic_int!(core::sync::atomic::AtomicI8);
159impl_atomic_int!(core::sync::atomic::AtomicI16);
160impl_atomic_int!(core::sync::atomic::AtomicI32);
161impl_atomic_int!(core::sync::atomic::AtomicI64);
162impl_atomic_int!(core::sync::atomic::AtomicIsize);
163
164#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
166pub struct EncodeMinimizeInt<N>(pub N);
167
168impl<W, N> Encode<W> for EncodeMinimizeInt<N>
169where
170 W: IoWrite,
171 N: ToPrimitive,
172{
173 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
174 let n = &self.0;
175 if let Some(v) = n.to_u8() {
176 v.encode(writer)
177 } else if let Some(v) = n.to_i8() {
178 v.encode(writer)
179 } else if let Some(v) = n.to_u16() {
180 v.encode(writer)
181 } else if let Some(v) = n.to_i16() {
182 v.encode(writer)
183 } else if let Some(v) = n.to_u32() {
184 v.encode(writer)
185 } else if let Some(v) = n.to_i32() {
186 v.encode(writer)
187 } else if let Some(v) = n.to_u64() {
188 v.encode(writer)
189 } else if let Some(v) = n.to_i64() {
190 v.encode(writer)
191 } else {
192 Err(Error::InvalidFormat)
193 }
194 }
195}
196
197#[cfg(test)]
198mod tests {
199 use super::*;
200 use rstest::rstest;
201
202 #[rstest]
203 #[case(u8::MIN,[0x00])]
204 #[case(0x7f_u8,[0x7f])]
205 #[case(0x80_u8,[Format::Uint8.as_byte(), 0x80])]
206 #[case(u8::MAX,[Format::Uint8.as_byte(), 0xff])]
207 fn encode_uint8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
208 #[case] value: V,
209 #[case] expected: E,
210 ) {
211 let expected = expected.as_ref();
212
213 let mut buf: Vec<u8> = vec![];
214 let n = value.encode(&mut buf).unwrap();
215 assert_eq!(buf, expected);
216 assert_eq!(n, expected.len());
217 }
218
219 #[rstest]
220 #[case(u16::MIN,[Format::Uint16.as_byte(),0x00,0x00])]
221 #[case(0x00ff_u16,[Format::Uint16.as_byte(),0x00,0xff])]
222 #[case(0x01ff_u16, [Format::Uint16.as_byte(), 0x01, 0xff])]
223 #[case(u16::MAX, [Format::Uint16.as_byte(), 0xff, 0xff])]
224 fn encode_uint16<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
225 let expected = expected.as_ref();
226
227 let mut buf = vec![];
228 let n = value.encode(&mut buf).unwrap();
229 assert_eq!(buf, expected);
230 assert_eq!(n, expected.len());
231 }
232
233 #[rstest]
234 #[case(u32::MIN, [Format::Uint32.as_byte(), 0x00, 0x00,0x00, 0x00])]
235 #[case(0x0000ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x00,0xff, 0xff])]
236 #[case(0x0001ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x01,0xff, 0xff])]
237 #[case(u32::MAX, [Format::Uint32.as_byte(),0xff, 0xff, 0xff,0xff])]
238 fn encode_uint32<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
239 let expected = expected.as_ref();
240
241 let mut buf = vec![];
242 let n = value.encode(&mut buf).unwrap();
243 assert_eq!(buf, expected);
244 assert_eq!(n, expected.len());
245 }
246
247 #[rstest]
248 #[case(u64::MIN, [Format::Uint64.as_byte(), 0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00])]
249 #[case(u64::MAX, [Format::Uint64.as_byte(), 0xff, 0xff, 0xff,0xff,0xff, 0xff, 0xff,0xff])]
250 fn encode_uint64<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
251 let expected = expected.as_ref();
252
253 let mut buf = vec![];
254 let n = value.encode(&mut buf).unwrap();
255 assert_eq!(buf, expected);
256 assert_eq!(n, expected.len());
257 }
258
259 #[rstest]
260 #[case(i8::MIN,[Format::Int8.as_byte(),0x80])]
261 #[case(-32_i8,[0xe0])]
262 #[case(-1_i8,[0xff])]
263 #[case(0_i8,[Format::Int8.as_byte(),0x00])]
264 #[case(i8::MAX,[Format::Int8.as_byte(),0x7f])]
265 fn encode_int8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
266 #[case] value: V,
267 #[case] expected: E,
268 ) {
269 let expected = expected.as_ref();
270
271 let mut buf = vec![];
272 let n = value.encode(&mut buf).unwrap();
273 assert_eq!(buf, expected);
274 assert_eq!(n, expected.len());
275 }
276
277 #[rstest]
278 #[case(i16::MIN,[Format::Int16.as_byte(),0x80,0x00])]
279 #[case(-1_i16,[Format::Int16.as_byte(),0xff,0xff])]
280 #[case(0_i16,[Format::Int16.as_byte(),0x00,0x00])]
281 #[case(i16::MAX,[Format::Int16.as_byte(),0x7f,0xff])]
282 fn encode_int16<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
283 #[case] value: V,
284 #[case] expected: E,
285 ) {
286 let expected = expected.as_ref();
287
288 let mut buf = vec![];
289 let n = value.encode(&mut buf).unwrap();
290 assert_eq!(buf, expected);
291 assert_eq!(n, expected.len());
292 }
293
294 #[rstest]
295 #[case(i32::MIN,[Format::Int32.as_byte(),0x80,0x00,0x00,0x00])]
296 #[case(-1_i32,[Format::Int32.as_byte(),0xff,0xff,0xff,0xff])]
297 #[case(0_i32,[Format::Int32.as_byte(),0x00,0x00,0x00,0x00])]
298 #[case(i32::MAX,[Format::Int32.as_byte(),0x7f,0xff,0xff,0xff])]
299 fn encode_int32<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
300 #[case] value: V,
301 #[case] expected: E,
302 ) {
303 let expected = expected.as_ref();
304
305 let mut buf = vec![];
306 let n = value.encode(&mut buf).unwrap();
307 assert_eq!(buf, expected);
308 assert_eq!(n, expected.len());
309 }
310
311 #[rstest]
312 #[case(i64::MIN,[Format::Int64.as_byte(),0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
313 #[case(-1_i64,[Format::Int64.as_byte(),0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
314 #[case(0_i64,[Format::Int64.as_byte(),0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
315 #[case(i64::MAX,[Format::Int64.as_byte(),0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
316 fn encode_int64<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
317 #[case] value: V,
318 #[case] expected: E,
319 ) {
320 let expected = expected.as_ref();
321
322 let mut buf = vec![];
323 let n = value.encode(&mut buf).unwrap();
324 assert_eq!(buf, expected);
325 assert_eq!(n, expected.len());
326 }
327
328 #[rstest]
329 #[case(0_i8,[0x00])]
330 #[case(0x7f_i8,[0x7f])]
331 #[case(0_u16,[0x00])]
332 #[case(0x7f_u16,[0x7f])]
333 #[case(0x80_u16,[Format::Uint8.as_byte(),0x80])]
334 #[case(0_i16,[0x00])]
335 #[case(0x7f_i16,[0x7f])]
336 #[case(0_u32,[0x00])]
337 #[case(0_u64,[0x00])]
338 #[case(0_u128,[0x00])]
339 #[case(0_i32,[0x00])]
340 #[case(0_i64,[0x00])]
341 #[case(0_i128,[0x00])]
342 #[case(3.0_f32,[0x03])]
343 fn encode_int_minimize<V: ToPrimitive, E: AsRef<[u8]> + Sized>(
344 #[case] value: V,
345 #[case] expected: E,
346 ) {
347 let expected = expected.as_ref();
348 let encoder = EncodeMinimizeInt(value);
349
350 let mut buf = vec![];
351 let n = encoder.encode(&mut buf).unwrap();
352 assert_eq!(buf, expected);
353 assert_eq!(n, expected.len());
354 }
355}