Skip to main content

messagepack_core/encode/
int.rs

1//! Integer encoders and size‑minimising helpers.
2
3use 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/// encode minimum byte size
165#[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}