bincode/varint/
encode_signed.rs

1use super::{varint_encode_u128, varint_encode_u16, varint_encode_u32, varint_encode_u64};
2use crate::{config::Endianness, enc::write::Writer, error::EncodeError};
3
4pub fn varint_encode_i16<W: Writer>(
5    writer: &mut W,
6    endian: Endianness,
7    val: i16,
8) -> Result<(), EncodeError> {
9    varint_encode_u16(
10        writer,
11        endian,
12        if val < 0 {
13            // let's avoid the edge case of i16::min_value()
14            // !n is equal to `-n - 1`, so this is:
15            // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
16            !(val as u16) * 2 + 1
17        } else {
18            (val as u16) * 2
19        },
20    )
21}
22
23pub fn varint_encode_i32<W: Writer>(
24    writer: &mut W,
25    endian: Endianness,
26    val: i32,
27) -> Result<(), EncodeError> {
28    varint_encode_u32(
29        writer,
30        endian,
31        if val < 0 {
32            // let's avoid the edge case of i32::min_value()
33            // !n is equal to `-n - 1`, so this is:
34            // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
35            !(val as u32) * 2 + 1
36        } else {
37            (val as u32) * 2
38        },
39    )
40}
41
42pub fn varint_encode_i64<W: Writer>(
43    writer: &mut W,
44    endian: Endianness,
45    val: i64,
46) -> Result<(), EncodeError> {
47    varint_encode_u64(
48        writer,
49        endian,
50        if val < 0 {
51            // let's avoid the edge case of i64::min_value()
52            // !n is equal to `-n - 1`, so this is:
53            // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
54            !(val as u64) * 2 + 1
55        } else {
56            (val as u64) * 2
57        },
58    )
59}
60
61pub fn varint_encode_i128<W: Writer>(
62    writer: &mut W,
63    endian: Endianness,
64    val: i128,
65) -> Result<(), EncodeError> {
66    varint_encode_u128(
67        writer,
68        endian,
69        if val < 0 {
70            // let's avoid the edge case of i128::min_value()
71            // !n is equal to `-n - 1`, so this is:
72            // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
73            !(val as u128) * 2 + 1
74        } else {
75            (val as u128) * 2
76        },
77    )
78}
79
80pub fn varint_encode_isize<W: Writer>(
81    writer: &mut W,
82    endian: Endianness,
83    val: isize,
84) -> Result<(), EncodeError> {
85    // isize is being encoded as a i64
86    varint_encode_i64(writer, endian, val as i64)
87}
88
89#[test]
90fn test_encode_i16() {
91    let cases: &[(i16, &[u8], &[u8])] = &[
92        (0, &[0], &[0]),
93        (2, &[4], &[4]),
94        (256, &[super::U16_BYTE, 0, 2], &[super::U16_BYTE, 2, 0]),
95        (
96            16_000,
97            &[super::U16_BYTE, 0, 125],
98            &[super::U16_BYTE, 125, 0],
99        ),
100        (
101            i16::MAX - 1,
102            &[super::U16_BYTE, 252, 255],
103            &[super::U16_BYTE, 255, 252],
104        ),
105        (
106            i16::MAX,
107            &[super::U16_BYTE, 254, 255],
108            &[super::U16_BYTE, 255, 254],
109        ),
110    ];
111
112    use crate::enc::write::SliceWriter;
113    let mut buffer = [0u8; 20];
114    for &(value, expected_le, expected_be) in cases {
115        std::dbg!(value);
116
117        // Little endian
118        let mut writer = SliceWriter::new(&mut buffer);
119        varint_encode_i16(&mut writer, Endianness::Little, value).unwrap();
120
121        assert_eq!(writer.bytes_written(), expected_le.len());
122        assert_eq!(&buffer[..expected_le.len()], expected_le);
123
124        // Big endian
125        let mut writer = SliceWriter::new(&mut buffer);
126        varint_encode_i16(&mut writer, Endianness::Big, value).unwrap();
127
128        assert_eq!(writer.bytes_written(), expected_be.len());
129        assert_eq!(&buffer[..expected_be.len()], expected_be);
130    }
131}
132
133#[test]
134fn test_encode_i32() {
135    let cases: &[(i32, &[u8], &[u8])] = &[
136        (0, &[0], &[0]),
137        (2, &[4], &[4]),
138        (256, &[super::U16_BYTE, 0, 2], &[super::U16_BYTE, 2, 0]),
139        (
140            16_000,
141            &[super::U16_BYTE, 0, 125],
142            &[super::U16_BYTE, 125, 0],
143        ),
144        (
145            40_000,
146            &[super::U32_BYTE, 128, 56, 1, 0],
147            &[super::U32_BYTE, 0, 1, 56, 128],
148        ),
149        (
150            i32::MAX - 1,
151            &[super::U32_BYTE, 252, 255, 255, 255],
152            &[super::U32_BYTE, 255, 255, 255, 252],
153        ),
154        (
155            i32::MAX,
156            &[super::U32_BYTE, 254, 255, 255, 255],
157            &[super::U32_BYTE, 255, 255, 255, 254],
158        ),
159    ];
160
161    use crate::enc::write::SliceWriter;
162    let mut buffer = [0u8; 20];
163    for &(value, expected_le, expected_be) in cases {
164        std::dbg!(value);
165
166        // Little endian
167        let mut writer = SliceWriter::new(&mut buffer);
168        varint_encode_i32(&mut writer, Endianness::Little, value).unwrap();
169
170        assert_eq!(writer.bytes_written(), expected_le.len());
171        assert_eq!(&buffer[..expected_le.len()], expected_le);
172
173        // Big endian
174        let mut writer = SliceWriter::new(&mut buffer);
175        varint_encode_i32(&mut writer, Endianness::Big, value).unwrap();
176
177        assert_eq!(writer.bytes_written(), expected_be.len());
178        assert_eq!(&buffer[..expected_be.len()], expected_be);
179    }
180}
181
182#[test]
183fn test_encode_i64() {
184    let cases: &[(i64, &[u8], &[u8])] = &[
185        (0, &[0], &[0]),
186        (2, &[4], &[4]),
187        (256, &[super::U16_BYTE, 0, 2], &[super::U16_BYTE, 2, 0]),
188        (
189            16_000,
190            &[super::U16_BYTE, 0, 125],
191            &[super::U16_BYTE, 125, 0],
192        ),
193        (
194            40_000,
195            &[super::U32_BYTE, 128, 56, 1, 0],
196            &[super::U32_BYTE, 0, 1, 56, 128],
197        ),
198        (
199            3_000_000_000,
200            &[super::U64_BYTE, 0, 188, 160, 101, 1, 0, 0, 0],
201            &[super::U64_BYTE, 0, 0, 0, 1, 101, 160, 188, 0],
202        ),
203        (
204            i64::MAX - 1,
205            &[super::U64_BYTE, 252, 255, 255, 255, 255, 255, 255, 255],
206            &[super::U64_BYTE, 255, 255, 255, 255, 255, 255, 255, 252],
207        ),
208        (
209            i64::MAX,
210            &[super::U64_BYTE, 254, 255, 255, 255, 255, 255, 255, 255],
211            &[super::U64_BYTE, 255, 255, 255, 255, 255, 255, 255, 254],
212        ),
213    ];
214
215    use crate::enc::write::SliceWriter;
216    let mut buffer = [0u8; 20];
217    for &(value, expected_le, expected_be) in cases {
218        std::dbg!(value);
219
220        // Little endian
221        let mut writer = SliceWriter::new(&mut buffer);
222        varint_encode_i64(&mut writer, Endianness::Little, value).unwrap();
223
224        assert_eq!(writer.bytes_written(), expected_le.len());
225        assert_eq!(&buffer[..expected_le.len()], expected_le);
226
227        // Big endian
228        let mut writer = SliceWriter::new(&mut buffer);
229        varint_encode_i64(&mut writer, Endianness::Big, value).unwrap();
230
231        assert_eq!(writer.bytes_written(), expected_be.len());
232        assert_eq!(&buffer[..expected_be.len()], expected_be);
233    }
234}
235
236#[test]
237fn test_encode_i128() {
238    #[rustfmt::skip]
239    let cases: &[(i128, &[u8], &[u8])] = &[
240        (0, &[0], &[0]),
241        (2, &[4], &[4]),
242        (256, &[super::U16_BYTE, 0, 2], &[super::U16_BYTE, 2, 0]),
243        (
244            16_000,
245            &[super::U16_BYTE, 0, 125],
246            &[super::U16_BYTE, 125, 0],
247        ),
248        (
249            40_000,
250            &[super::U32_BYTE, 128, 56, 1, 0],
251            &[super::U32_BYTE, 0, 1, 56, 128],
252        ),
253        (
254            3_000_000_000,
255            &[super::U64_BYTE, 0, 188, 160, 101, 1, 0, 0, 0],
256            &[super::U64_BYTE, 0, 0, 0, 1, 101, 160, 188, 0],
257        ),
258        (
259            11_000_000_000_000_000_000,
260            &[
261                super::U128_BYTE,
262                0, 0, 152, 98, 112, 179, 79, 49,
263                1, 0, 0, 0, 0, 0, 0, 0,
264            ],
265            &[
266                super::U128_BYTE,
267                0, 0, 0, 0, 0, 0, 0, 1,
268                49, 79, 179, 112, 98, 152, 0, 0,
269            ],
270        ),
271        (
272            i128::MAX - 1,
273            &[
274                super::U128_BYTE,
275                252, 255, 255, 255, 255, 255, 255, 255,
276                255, 255, 255, 255, 255, 255, 255, 255,
277            ],
278            &[
279                super::U128_BYTE,
280                255, 255, 255, 255, 255, 255, 255, 255,
281                255, 255, 255, 255, 255, 255, 255, 252,
282            ],
283        ),
284        (
285            i128::MAX,
286            &[
287                super::U128_BYTE,
288                254, 255, 255, 255, 255, 255, 255, 255,
289                255, 255, 255, 255, 255, 255, 255, 255,
290            ],
291            &[
292                super::U128_BYTE,
293                255, 255, 255, 255, 255, 255, 255, 255,
294                255, 255, 255, 255, 255, 255, 255, 254,
295            ],
296        ),
297    ];
298
299    use crate::enc::write::SliceWriter;
300    let mut buffer = [0u8; 20];
301    for &(value, expected_le, expected_be) in cases {
302        std::dbg!(value);
303
304        // Little endian
305        let mut writer = SliceWriter::new(&mut buffer);
306        varint_encode_i128(&mut writer, Endianness::Little, value).unwrap();
307
308        assert_eq!(writer.bytes_written(), expected_le.len());
309        assert_eq!(&buffer[..expected_le.len()], expected_le);
310
311        // Big endian
312        let mut writer = SliceWriter::new(&mut buffer);
313        varint_encode_i128(&mut writer, Endianness::Big, value).unwrap();
314
315        assert_eq!(writer.bytes_written(), expected_be.len());
316        assert_eq!(&buffer[..expected_be.len()], expected_be);
317    }
318}