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
72macro_rules! impl_encode_int {
73    ($ty:ty,  $format:expr, $size:expr) => {
74        impl<W> Encode<W> for $ty
75        where
76            W: IoWrite,
77        {
78            fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
79                writer.write(&$format.as_slice())?;
80                writer.write(&self.to_be_bytes())?;
81                Ok($size)
82            }
83        }
84    };
85}
86
87impl<W> Encode<W> for isize
88where
89    W: IoWrite,
90{
91    fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
92        match i64::try_from(*self) {
93            Ok(i64_int) => i64_int.encode(writer),
94            Err(_) => Err(Error::InvalidFormat),
95        }
96    }
97}
98
99impl<W> Encode<W> for i128
100where
101    W: IoWrite,
102{
103    fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
104        match i64::try_from(*self) {
105            Ok(i64_int) => i64_int.encode(writer),
106            Err(_) => Err(Error::InvalidFormat),
107        }
108    }
109}
110
111impl_encode_int!(u16, Format::Uint16, 3);
112impl_encode_int!(u32, Format::Uint32, 5);
113impl_encode_int!(u64, Format::Uint64, 9);
114impl_encode_int!(i16, Format::Int16, 3);
115impl_encode_int!(i32, Format::Int32, 5);
116impl_encode_int!(i64, Format::Int64, 9);
117
118/// encode minimum byte size
119#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
120pub struct EncodeMinimizeInt<N>(pub N);
121
122impl<W, N> Encode<W> for EncodeMinimizeInt<N>
123where
124    W: IoWrite,
125    N: ToPrimitive,
126{
127    fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
128        let n = &self.0;
129        if let Some(v) = n.to_u8() {
130            v.encode(writer)
131        } else if let Some(v) = n.to_i8() {
132            v.encode(writer)
133        } else if let Some(v) = n.to_u16() {
134            v.encode(writer)
135        } else if let Some(v) = n.to_i16() {
136            v.encode(writer)
137        } else if let Some(v) = n.to_u32() {
138            v.encode(writer)
139        } else if let Some(v) = n.to_i32() {
140            v.encode(writer)
141        } else if let Some(v) = n.to_u64() {
142            v.encode(writer)
143        } else if let Some(v) = n.to_i64() {
144            v.encode(writer)
145        } else {
146            Err(Error::InvalidFormat)
147        }
148    }
149}
150
151#[cfg(test)]
152mod tests {
153    use super::*;
154    use rstest::rstest;
155
156    #[rstest]
157    #[case(u8::MIN,[0x00])]
158    #[case(0x7f_u8,[0x7f])]
159    #[case(0x80_u8,[Format::Uint8.as_byte(), 0x80])]
160    #[case(u8::MAX,[Format::Uint8.as_byte(), 0xff])]
161    fn encode_uint8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
162        #[case] value: V,
163        #[case] expected: E,
164    ) {
165        let expected = expected.as_ref();
166
167        let mut buf: Vec<u8> = vec![];
168        let n = value.encode(&mut buf).unwrap();
169        assert_eq!(buf, expected);
170        assert_eq!(n, expected.len());
171    }
172
173    #[rstest]
174    #[case(u16::MIN,[Format::Uint16.as_byte(),0x00,0x00])]
175    #[case(0x00ff_u16,[Format::Uint16.as_byte(),0x00,0xff])]
176    #[case(0x01ff_u16, [Format::Uint16.as_byte(), 0x01, 0xff])]
177    #[case(u16::MAX, [Format::Uint16.as_byte(), 0xff, 0xff])]
178    fn encode_uint16<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
179        let expected = expected.as_ref();
180
181        let mut buf = vec![];
182        let n = value.encode(&mut buf).unwrap();
183        assert_eq!(buf, expected);
184        assert_eq!(n, expected.len());
185    }
186
187    #[rstest]
188    #[case(u32::MIN, [Format::Uint32.as_byte(), 0x00, 0x00,0x00, 0x00])]
189    #[case(0x0000ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x00,0xff, 0xff])]
190    #[case(0x0001ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x01,0xff, 0xff])]
191    #[case(u32::MAX, [Format::Uint32.as_byte(),0xff, 0xff, 0xff,0xff])]
192    fn encode_uint32<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
193        let expected = expected.as_ref();
194
195        let mut buf = vec![];
196        let n = value.encode(&mut buf).unwrap();
197        assert_eq!(buf, expected);
198        assert_eq!(n, expected.len());
199    }
200
201    #[rstest]
202    #[case(u64::MIN, [Format::Uint64.as_byte(), 0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00])]
203    #[case(u64::MAX, [Format::Uint64.as_byte(), 0xff, 0xff, 0xff,0xff,0xff, 0xff, 0xff,0xff])]
204    fn encode_uint64<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
205        let expected = expected.as_ref();
206
207        let mut buf = vec![];
208        let n = value.encode(&mut buf).unwrap();
209        assert_eq!(buf, expected);
210        assert_eq!(n, expected.len());
211    }
212
213    #[rstest]
214    #[case(i8::MIN,[Format::Int8.as_byte(),0x80])]
215    #[case(-32_i8,[0xe0])]
216    #[case(-1_i8,[0xff])]
217    #[case(0_i8,[Format::Int8.as_byte(),0x00])]
218    #[case(i8::MAX,[Format::Int8.as_byte(),0x7f])]
219    fn encode_int8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
220        #[case] value: V,
221        #[case] expected: E,
222    ) {
223        let expected = expected.as_ref();
224
225        let mut buf = vec![];
226        let n = value.encode(&mut buf).unwrap();
227        assert_eq!(buf, expected);
228        assert_eq!(n, expected.len());
229    }
230
231    #[rstest]
232    #[case(i16::MIN,[Format::Int16.as_byte(),0x80,0x00])]
233    #[case(-1_i16,[Format::Int16.as_byte(),0xff,0xff])]
234    #[case(0_i16,[Format::Int16.as_byte(),0x00,0x00])]
235    #[case(i16::MAX,[Format::Int16.as_byte(),0x7f,0xff])]
236    fn encode_int16<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
237        #[case] value: V,
238        #[case] expected: E,
239    ) {
240        let expected = expected.as_ref();
241
242        let mut buf = vec![];
243        let n = value.encode(&mut buf).unwrap();
244        assert_eq!(buf, expected);
245        assert_eq!(n, expected.len());
246    }
247
248    #[rstest]
249    #[case(i32::MIN,[Format::Int32.as_byte(),0x80,0x00,0x00,0x00])]
250    #[case(-1_i32,[Format::Int32.as_byte(),0xff,0xff,0xff,0xff])]
251    #[case(0_i32,[Format::Int32.as_byte(),0x00,0x00,0x00,0x00])]
252    #[case(i32::MAX,[Format::Int32.as_byte(),0x7f,0xff,0xff,0xff])]
253    fn encode_int32<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
254        #[case] value: V,
255        #[case] expected: E,
256    ) {
257        let expected = expected.as_ref();
258
259        let mut buf = vec![];
260        let n = value.encode(&mut buf).unwrap();
261        assert_eq!(buf, expected);
262        assert_eq!(n, expected.len());
263    }
264
265    #[rstest]
266    #[case(i64::MIN,[Format::Int64.as_byte(),0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
267    #[case(-1_i64,[Format::Int64.as_byte(),0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
268    #[case(0_i64,[Format::Int64.as_byte(),0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
269    #[case(i64::MAX,[Format::Int64.as_byte(),0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
270    fn encode_int64<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
271        #[case] value: V,
272        #[case] expected: E,
273    ) {
274        let expected = expected.as_ref();
275
276        let mut buf = vec![];
277        let n = value.encode(&mut buf).unwrap();
278        assert_eq!(buf, expected);
279        assert_eq!(n, expected.len());
280    }
281
282    #[rstest]
283    #[case(0_i8,[0x00])]
284    #[case(0x7f_i8,[0x7f])]
285    #[case(0_u16,[0x00])]
286    #[case(0x7f_u16,[0x7f])]
287    #[case(0x80_u16,[Format::Uint8.as_byte(),0x80])]
288    #[case(0_i16,[0x00])]
289    #[case(0x7f_i16,[0x7f])]
290    #[case(0_u32,[0x00])]
291    #[case(0_u64,[0x00])]
292    #[case(0_u128,[0x00])]
293    #[case(0_i32,[0x00])]
294    #[case(0_i64,[0x00])]
295    #[case(0_i128,[0x00])]
296    #[case(3.0_f32,[0x03])]
297    fn encode_int_minimize<V: ToPrimitive, E: AsRef<[u8]> + Sized>(
298        #[case] value: V,
299        #[case] expected: E,
300    ) {
301        let expected = expected.as_ref();
302        let encoder = EncodeMinimizeInt(value);
303
304        let mut buf = vec![];
305        let n = encoder.encode(&mut buf).unwrap();
306        assert_eq!(buf, expected);
307        assert_eq!(n, expected.len());
308    }
309}