Skip to main content

float_pigment_consistent_bincode/config/
int.rs

1use alloc::{boxed::Box, string::ToString};
2use core::mem::size_of;
3
4use super::Options;
5use crate::de::read::BincodeRead;
6use crate::error::{ErrorKind, Result};
7use crate::io::Write;
8
9pub trait IntEncoding {
10    /// Gets the size (in bytes) that a value would be serialized to.
11    fn u16_size(n: u16) -> u64;
12    /// Gets the size (in bytes) that a value would be serialized to.
13    fn u32_size(n: u32) -> u64;
14    /// Gets the size (in bytes) that a value would be serialized to.
15    fn u64_size(n: u64) -> u64;
16
17    /// Gets the size (in bytes) that a value would be serialized to.
18    fn i16_size(n: i16) -> u64;
19    /// Gets the size (in bytes) that a value would be serialized to.
20    fn i32_size(n: i32) -> u64;
21    /// Gets the size (in bytes) that a value would be serialized to.
22    fn i64_size(n: i64) -> u64;
23
24    #[inline(always)]
25    fn len_size(len: usize) -> u64 {
26        Self::u64_size(len as u64)
27    }
28
29    /// Serializes a sequence length.
30    #[inline(always)]
31    fn serialize_len<W: Write, O: Options>(
32        ser: &mut crate::ser::Serializer<W, O>,
33        len: usize,
34    ) -> Result<()> {
35        Self::serialize_u64(ser, len as u64)
36    }
37
38    fn serialize_u16<W: Write, O: Options>(
39        ser: &mut crate::ser::Serializer<W, O>,
40        val: u16,
41    ) -> Result<()>;
42
43    fn serialize_u32<W: Write, O: Options>(
44        ser: &mut crate::ser::Serializer<W, O>,
45        val: u32,
46    ) -> Result<()>;
47
48    fn serialize_u64<W: Write, O: Options>(
49        ser: &mut crate::ser::Serializer<W, O>,
50        val: u64,
51    ) -> Result<()>;
52
53    fn serialize_i16<W: Write, O: Options>(
54        ser: &mut crate::ser::Serializer<W, O>,
55        val: i16,
56    ) -> Result<()>;
57
58    fn serialize_i32<W: Write, O: Options>(
59        ser: &mut crate::ser::Serializer<W, O>,
60        val: i32,
61    ) -> Result<()>;
62
63    fn serialize_i64<W: Write, O: Options>(
64        ser: &mut crate::ser::Serializer<W, O>,
65        val: i64,
66    ) -> Result<()>;
67
68    /// Deserializes a sequence length.
69    #[inline(always)]
70    fn deserialize_len<'de, R: BincodeRead<'de>, O: Options>(
71        de: &mut crate::de::Deserializer<R, O>,
72    ) -> Result<usize> {
73        Self::deserialize_u64(de).and_then(cast_u64_to_usize)
74    }
75
76    fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
77        de: &mut crate::de::Deserializer<R, O>,
78    ) -> Result<u16>;
79
80    fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
81        de: &mut crate::de::Deserializer<R, O>,
82    ) -> Result<u32>;
83
84    fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
85        de: &mut crate::de::Deserializer<R, O>,
86    ) -> Result<u64>;
87
88    fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
89        de: &mut crate::de::Deserializer<R, O>,
90    ) -> Result<i16>;
91
92    fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
93        de: &mut crate::de::Deserializer<R, O>,
94    ) -> Result<i32>;
95
96    fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
97        de: &mut crate::de::Deserializer<R, O>,
98    ) -> Result<i64>;
99
100    serde_if_integer128! {
101        fn u128_size(v: u128) -> u64;
102        fn i128_size(v: i128) -> u64;
103        fn serialize_u128<W: Write, O: Options>(
104            ser: &mut crate::Serializer<W, O>,
105            val: u128,
106        ) -> Result<()>;
107        fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
108            de: &mut crate::Deserializer<R, O>,
109        ) -> Result<u128>;
110        fn serialize_i128<W: Write, O: Options>(
111            ser: &mut crate::Serializer<W, O>,
112            val: i128,
113        ) -> Result<()>;
114        fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
115            de: &mut crate::Deserializer<R, O>,
116        ) -> Result<i128>;
117    }
118}
119
120/// Fixed-size integer encoding.
121///
122/// * Fixed size integers are encoded directly
123/// * Enum discriminants are encoded as u32
124/// * Lengths and usize are encoded as u64
125#[derive(Copy, Clone)]
126pub struct FixintEncoding;
127
128/// Variable-size integer encoding (excepting [ui]8).
129///
130/// Encoding an unsigned integer v (of any type excepting u8) works as follows:
131///
132/// 1. If `u < 251`, encode it as a single byte with that value.
133/// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
134/// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`.
135/// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
136/// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a u128 with value `u`.
137///
138/// Then, for signed integers, we first convert to unsigned using the zigzag algorithm,
139/// and then encode them as we do for unsigned integers generally. The reason we use this
140/// algorithm is that it encodes those values which are close to zero in less bytes; the
141/// obvious algorithm, where we encode the cast values, gives a very large encoding for all
142/// negative values.
143///
144/// The zigzag algorithm is defined as follows:
145///
146/// ```ignore
147/// fn zigzag(v: Signed) -> Unsigned {
148///     match v {
149///         0 => 0,
150///         v if v < 0 => |v| * 2 - 1
151///         v if v > 0 => v * 2
152///     }
153/// }
154/// ```
155///
156/// And works such that:
157///
158/// ```ignore
159/// assert_eq!(zigzag(0), 0);
160/// assert_eq!(zigzag(-1), 1);
161/// assert_eq!(zigzag(1), 2);
162/// assert_eq!(zigzag(-2), 3);
163/// assert_eq!(zigzag(2), 4);
164/// assert_eq!(zigzag(i64::min_value()), u64::max_value());
165/// ```
166///
167/// Note that u256 and the like are unsupported by this format; if and when they are added to the
168/// language, they may be supported via the extension point given by the 255 byte.
169#[derive(Copy, Clone)]
170pub struct VarintEncoding;
171
172const SINGLE_BYTE_MAX: u8 = 250;
173const U16_BYTE: u8 = 251;
174const U32_BYTE: u8 = 252;
175const U64_BYTE: u8 = 253;
176const U128_BYTE: u8 = 254;
177const DESERIALIZE_EXTENSION_POINT_ERR: &str = r#"
178Byte 255 is treated as an extension point; it should not be encoding anything.
179Do you have a mismatched bincode version or configuration?
180"#;
181
182impl VarintEncoding {
183    fn varint_size(n: u64) -> u64 {
184        if n <= SINGLE_BYTE_MAX as u64 {
185            1
186        } else if n <= u16::max_value() as u64 {
187            (1 + size_of::<u16>()) as u64
188        } else if n <= u32::max_value() as u64 {
189            (1 + size_of::<u32>()) as u64
190        } else {
191            (1 + size_of::<u64>()) as u64
192        }
193    }
194
195    #[inline(always)]
196    fn zigzag_encode(n: i64) -> u64 {
197        if n < 0 {
198            // let's avoid the edge case of i64::min_value()
199            // !n is equal to `-n - 1`, so this is:
200            // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
201            !(n as u64) * 2 + 1
202        } else {
203            (n as u64) * 2
204        }
205    }
206
207    #[inline(always)]
208    fn zigzag_decode(n: u64) -> i64 {
209        if n.is_multiple_of(2) {
210            // positive number
211            (n / 2) as i64
212        } else {
213            // negative number
214            // !m * 2 + 1 = n
215            // !m * 2 = n - 1
216            // !m = (n - 1) / 2
217            // m = !((n - 1) / 2)
218            // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2)
219            !(n / 2) as i64
220        }
221    }
222
223    fn serialize_varint<W: Write, O: Options>(
224        ser: &mut crate::ser::Serializer<W, O>,
225        n: u64,
226    ) -> Result<()> {
227        if n <= SINGLE_BYTE_MAX as u64 {
228            ser.serialize_byte(n as u8)
229        } else if n <= u16::max_value() as u64 {
230            ser.serialize_byte(U16_BYTE)?;
231            ser.serialize_literal_u16(n as u16)
232        } else if n <= u32::max_value() as u64 {
233            ser.serialize_byte(U32_BYTE)?;
234            ser.serialize_literal_u32(n as u32)
235        } else {
236            ser.serialize_byte(U64_BYTE)?;
237            ser.serialize_literal_u64(n)
238        }
239    }
240
241    fn deserialize_varint<'de, R: BincodeRead<'de>, O: Options>(
242        de: &mut crate::de::Deserializer<R, O>,
243    ) -> Result<u64> {
244        #[allow(ellipsis_inclusive_range_patterns)]
245        match de.deserialize_byte()? {
246            byte @ 0..=SINGLE_BYTE_MAX => Ok(byte as u64),
247            U16_BYTE => Ok(de.deserialize_literal_u16()? as u64),
248            U32_BYTE => Ok(de.deserialize_literal_u32()? as u64),
249            U64_BYTE => de.deserialize_literal_u64(),
250            U128_BYTE => Err(Box::new(ErrorKind::Custom(
251                "Invalid value (u128 range): you may have a version or configuration disagreement?"
252                    .to_string(),
253            ))),
254            _ => Err(Box::new(ErrorKind::Custom(
255                DESERIALIZE_EXTENSION_POINT_ERR.to_string(),
256            ))),
257        }
258    }
259
260    serde_if_integer128! {
261        // see zigzag_encode and zigzag_decode for implementation comments
262        #[inline(always)]
263        fn zigzag128_encode(n: i128) -> u128 {
264            if n < 0 {
265                !(n as u128) * 2 + 1
266            } else {
267                (n as u128) * 2
268            }
269        }
270        #[inline(always)]
271        fn zigzag128_decode(n: u128) -> i128 {
272            if n.is_multiple_of(2) {
273                (n / 2) as i128
274            } else {
275                !(n / 2) as i128
276            }
277        }
278
279        fn varint128_size(n: u128) -> u64 {
280            if n <= SINGLE_BYTE_MAX as u128 {
281                1
282            } else if n <= u16::max_value() as u128 {
283                (1 + size_of::<u16>()) as u64
284            } else if n <= u32::max_value() as u128 {
285                (1 + size_of::<u32>()) as u64
286            } else if n <= u64::max_value() as u128 {
287                (1 + size_of::<u64>()) as u64
288            } else {
289                (1 + size_of::<u128>()) as u64
290            }
291        }
292
293        fn serialize_varint128<W: Write, O: Options>(
294            ser: &mut crate::ser::Serializer<W, O>,
295            n: u128,
296        ) -> Result<()> {
297            if n <= SINGLE_BYTE_MAX as u128 {
298                ser.serialize_byte(n as u8)
299            } else if n <= u16::max_value() as u128 {
300                ser.serialize_byte(U16_BYTE)?;
301                ser.serialize_literal_u16(n as u16)
302            } else if n <= u32::max_value() as u128 {
303                ser.serialize_byte(U32_BYTE)?;
304                ser.serialize_literal_u32(n as u32)
305            } else if n <= u64::max_value() as u128 {
306                ser.serialize_byte(U64_BYTE)?;
307                ser.serialize_literal_u64(n as u64)
308            } else {
309                ser.serialize_byte(U128_BYTE)?;
310                ser.serialize_literal_u128(n)
311            }
312        }
313
314        fn deserialize_varint128<'de, R: BincodeRead<'de>, O: Options>(
315            de: &mut crate::de::Deserializer<R, O>,
316        ) -> Result<u128> {
317            #[allow(ellipsis_inclusive_range_patterns)]
318            match de.deserialize_byte()? {
319                byte @ 0..=SINGLE_BYTE_MAX => Ok(byte as u128),
320                U16_BYTE => Ok(de.deserialize_literal_u16()? as u128),
321                U32_BYTE => Ok(de.deserialize_literal_u32()? as u128),
322                U64_BYTE => Ok(de.deserialize_literal_u64()? as u128),
323                U128_BYTE => de.deserialize_literal_u128(),
324                _ => Err(Box::new(ErrorKind::Custom(DESERIALIZE_EXTENSION_POINT_ERR.to_string()))),
325            }
326        }
327    }
328}
329
330impl IntEncoding for FixintEncoding {
331    #[inline(always)]
332    fn u16_size(_: u16) -> u64 {
333        size_of::<u16>() as u64
334    }
335    #[inline(always)]
336    fn u32_size(_: u32) -> u64 {
337        size_of::<u32>() as u64
338    }
339    #[inline(always)]
340    fn u64_size(_: u64) -> u64 {
341        size_of::<u64>() as u64
342    }
343
344    #[inline(always)]
345    fn i16_size(_: i16) -> u64 {
346        size_of::<i16>() as u64
347    }
348    #[inline(always)]
349    fn i32_size(_: i32) -> u64 {
350        size_of::<i32>() as u64
351    }
352    #[inline(always)]
353    fn i64_size(_: i64) -> u64 {
354        size_of::<i64>() as u64
355    }
356
357    #[inline(always)]
358    fn serialize_u16<W: Write, O: Options>(
359        ser: &mut crate::Serializer<W, O>,
360        val: u16,
361    ) -> Result<()> {
362        ser.serialize_literal_u16(val)
363    }
364    #[inline(always)]
365    fn serialize_u32<W: Write, O: Options>(
366        ser: &mut crate::Serializer<W, O>,
367        val: u32,
368    ) -> Result<()> {
369        ser.serialize_literal_u32(val)
370    }
371    #[inline(always)]
372    fn serialize_u64<W: Write, O: Options>(
373        ser: &mut crate::Serializer<W, O>,
374        val: u64,
375    ) -> Result<()> {
376        ser.serialize_literal_u64(val)
377    }
378
379    #[inline(always)]
380    fn serialize_i16<W: Write, O: Options>(
381        ser: &mut crate::Serializer<W, O>,
382        val: i16,
383    ) -> Result<()> {
384        ser.serialize_literal_u16(val as u16)
385    }
386    #[inline(always)]
387    fn serialize_i32<W: Write, O: Options>(
388        ser: &mut crate::Serializer<W, O>,
389        val: i32,
390    ) -> Result<()> {
391        ser.serialize_literal_u32(val as u32)
392    }
393    #[inline(always)]
394    fn serialize_i64<W: Write, O: Options>(
395        ser: &mut crate::Serializer<W, O>,
396        val: i64,
397    ) -> Result<()> {
398        ser.serialize_literal_u64(val as u64)
399    }
400
401    #[inline(always)]
402    fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
403        de: &mut crate::Deserializer<R, O>,
404    ) -> Result<u16> {
405        de.deserialize_literal_u16()
406    }
407    #[inline(always)]
408    fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
409        de: &mut crate::Deserializer<R, O>,
410    ) -> Result<u32> {
411        de.deserialize_literal_u32()
412    }
413    #[inline(always)]
414    fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
415        de: &mut crate::Deserializer<R, O>,
416    ) -> Result<u64> {
417        de.deserialize_literal_u64()
418    }
419
420    #[inline(always)]
421    fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
422        de: &mut crate::Deserializer<R, O>,
423    ) -> Result<i16> {
424        Ok(de.deserialize_literal_u16()? as i16)
425    }
426    #[inline(always)]
427    fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
428        de: &mut crate::Deserializer<R, O>,
429    ) -> Result<i32> {
430        Ok(de.deserialize_literal_u32()? as i32)
431    }
432    #[inline(always)]
433    fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
434        de: &mut crate::Deserializer<R, O>,
435    ) -> Result<i64> {
436        Ok(de.deserialize_literal_u64()? as i64)
437    }
438
439    serde_if_integer128! {
440        #[inline(always)]
441        fn u128_size(_: u128) -> u64{
442            size_of::<u128>() as u64
443        }
444        #[inline(always)]
445        fn i128_size(_: i128) -> u64{
446            size_of::<i128>() as u64
447        }
448
449        #[inline(always)]
450        fn serialize_u128<W: Write, O: Options>(
451            ser: &mut crate::Serializer<W, O>,
452            val: u128,
453        ) -> Result<()> {
454            ser.serialize_literal_u128(val)
455        }
456        #[inline(always)]
457        fn serialize_i128<W: Write, O: Options>(
458            ser: &mut crate::Serializer<W, O>,
459            val: i128,
460        ) -> Result<()> {
461            ser.serialize_literal_u128(val as u128)
462        }
463        #[inline(always)]
464        fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
465            de: &mut crate::Deserializer<R, O>,
466        ) -> Result<u128> {
467            de.deserialize_literal_u128()
468        }
469        #[inline(always)]
470        fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
471            de: &mut crate::Deserializer<R, O>,
472        ) -> Result<i128> {
473            Ok(de.deserialize_literal_u128()? as i128)
474        }
475    }
476}
477
478impl IntEncoding for VarintEncoding {
479    #[inline(always)]
480    fn u16_size(n: u16) -> u64 {
481        Self::varint_size(n as u64)
482    }
483    #[inline(always)]
484    fn u32_size(n: u32) -> u64 {
485        Self::varint_size(n as u64)
486    }
487    #[inline(always)]
488    fn u64_size(n: u64) -> u64 {
489        Self::varint_size(n)
490    }
491
492    #[inline(always)]
493    fn i16_size(n: i16) -> u64 {
494        Self::varint_size(Self::zigzag_encode(n as i64))
495    }
496    #[inline(always)]
497    fn i32_size(n: i32) -> u64 {
498        Self::varint_size(Self::zigzag_encode(n as i64))
499    }
500    #[inline(always)]
501    fn i64_size(n: i64) -> u64 {
502        Self::varint_size(Self::zigzag_encode(n))
503    }
504
505    #[inline(always)]
506    fn serialize_u16<W: Write, O: Options>(
507        ser: &mut crate::Serializer<W, O>,
508        val: u16,
509    ) -> Result<()> {
510        Self::serialize_varint(ser, val as u64)
511    }
512    #[inline(always)]
513    fn serialize_u32<W: Write, O: Options>(
514        ser: &mut crate::Serializer<W, O>,
515        val: u32,
516    ) -> Result<()> {
517        Self::serialize_varint(ser, val as u64)
518    }
519    #[inline(always)]
520    fn serialize_u64<W: Write, O: Options>(
521        ser: &mut crate::Serializer<W, O>,
522        val: u64,
523    ) -> Result<()> {
524        Self::serialize_varint(ser, val)
525    }
526
527    #[inline(always)]
528    fn serialize_i16<W: Write, O: Options>(
529        ser: &mut crate::Serializer<W, O>,
530        val: i16,
531    ) -> Result<()> {
532        Self::serialize_varint(ser, Self::zigzag_encode(val as i64))
533    }
534    #[inline(always)]
535    fn serialize_i32<W: Write, O: Options>(
536        ser: &mut crate::Serializer<W, O>,
537        val: i32,
538    ) -> Result<()> {
539        Self::serialize_varint(ser, Self::zigzag_encode(val as i64))
540    }
541    #[inline(always)]
542    fn serialize_i64<W: Write, O: Options>(
543        ser: &mut crate::Serializer<W, O>,
544        val: i64,
545    ) -> Result<()> {
546        Self::serialize_varint(ser, Self::zigzag_encode(val))
547    }
548
549    #[inline(always)]
550    fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
551        de: &mut crate::Deserializer<R, O>,
552    ) -> Result<u16> {
553        Self::deserialize_varint(de).and_then(cast_u64_to_u16)
554    }
555    #[inline(always)]
556    fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
557        de: &mut crate::Deserializer<R, O>,
558    ) -> Result<u32> {
559        Self::deserialize_varint(de).and_then(cast_u64_to_u32)
560    }
561    #[inline(always)]
562    fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
563        de: &mut crate::Deserializer<R, O>,
564    ) -> Result<u64> {
565        Self::deserialize_varint(de)
566    }
567
568    #[inline(always)]
569    fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
570        de: &mut crate::Deserializer<R, O>,
571    ) -> Result<i16> {
572        Self::deserialize_varint(de)
573            .map(Self::zigzag_decode)
574            .and_then(cast_i64_to_i16)
575    }
576    #[inline(always)]
577    fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
578        de: &mut crate::Deserializer<R, O>,
579    ) -> Result<i32> {
580        Self::deserialize_varint(de)
581            .map(Self::zigzag_decode)
582            .and_then(cast_i64_to_i32)
583    }
584    #[inline(always)]
585    fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
586        de: &mut crate::Deserializer<R, O>,
587    ) -> Result<i64> {
588        Self::deserialize_varint(de).map(Self::zigzag_decode)
589    }
590
591    serde_if_integer128! {
592        #[inline(always)]
593        fn u128_size(n: u128) -> u64 {
594            Self::varint128_size(n)
595        }
596        #[inline(always)]
597        fn i128_size(n: i128) -> u64 {
598            Self::varint128_size(Self::zigzag128_encode(n))
599        }
600        #[inline(always)]
601        fn serialize_u128<W: Write, O: Options>(
602            ser: &mut crate::Serializer<W, O>,
603            val: u128,
604        ) -> Result<()> {
605            Self::serialize_varint128(ser, val)
606        }
607        #[inline(always)]
608        fn serialize_i128<W: Write, O: Options>(
609            ser: &mut crate::Serializer<W, O>,
610            val: i128,
611        ) -> Result<()> {
612            Self::serialize_varint128(ser, Self::zigzag128_encode(val))
613        }
614        #[inline(always)]
615        fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
616            de: &mut crate::Deserializer<R, O>,
617        ) -> Result<u128> {
618            Self::deserialize_varint128(de)
619        }
620        #[inline(always)]
621        fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
622            de: &mut crate::Deserializer<R, O>,
623        ) -> Result<i128> {
624            Self::deserialize_varint128(de).map(Self::zigzag128_decode)
625        }
626    }
627}
628
629fn cast_u64_to_usize(n: u64) -> Result<usize> {
630    if n <= usize::max_value() as u64 {
631        Ok(n as usize)
632    } else {
633        Err(Box::new(ErrorKind::Custom(format!(
634            "Invalid size {}: sizes must fit in a usize (0 to {})",
635            n,
636            usize::max_value()
637        ))))
638    }
639}
640fn cast_u64_to_u32(n: u64) -> Result<u32> {
641    if n <= u32::max_value() as u64 {
642        Ok(n as u32)
643    } else {
644        Err(Box::new(ErrorKind::Custom(format!(
645            "Invalid u32 {n}: you may have a version disagreement?",
646        ))))
647    }
648}
649fn cast_u64_to_u16(n: u64) -> Result<u16> {
650    if n <= u16::max_value() as u64 {
651        Ok(n as u16)
652    } else {
653        Err(Box::new(ErrorKind::Custom(format!(
654            "Invalid u16 {n}: you may have a version disagreement?",
655        ))))
656    }
657}
658
659fn cast_i64_to_i32(n: i64) -> Result<i32> {
660    if n <= i32::max_value() as i64 && n >= i32::min_value() as i64 {
661        Ok(n as i32)
662    } else {
663        Err(Box::new(ErrorKind::Custom(format!(
664            "Invalid i32 {n}: you may have a version disagreement?",
665        ))))
666    }
667}
668
669fn cast_i64_to_i16(n: i64) -> Result<i16> {
670    if n <= i16::max_value() as i64 && n >= i16::min_value() as i64 {
671        Ok(n as i16)
672    } else {
673        Err(Box::new(ErrorKind::Custom(format!(
674            "Invalid i16 {n}: you may have a version disagreement?",
675        ))))
676    }
677}
678
679#[cfg(test)]
680mod test {
681    use super::VarintEncoding;
682
683    #[test]
684    fn test_zigzag_encode() {
685        let zigzag = VarintEncoding::zigzag_encode;
686
687        assert_eq!(zigzag(0), 0);
688        for x in 1..512 {
689            assert_eq!(zigzag(x), (x as u64) * 2);
690            assert_eq!(zigzag(-x), (x as u64) * 2 - 1);
691        }
692    }
693
694    #[test]
695    fn test_zigzag_decode() {
696        // zigzag'
697        let zigzagp = VarintEncoding::zigzag_decode;
698        for x in (0..512).map(|x| x * 2) {
699            assert_eq!(zigzagp(x), x as i64 / 2);
700            assert_eq!(zigzagp(x + 1), -(x as i64) / 2 - 1);
701        }
702    }
703
704    #[test]
705    fn test_zigzag_edge_cases() {
706        let (zigzag, zigzagp) = (VarintEncoding::zigzag_encode, VarintEncoding::zigzag_decode);
707
708        assert_eq!(zigzag(i64::max_value()), u64::max_value() - 1);
709        assert_eq!(zigzag(i64::min_value()), u64::max_value());
710
711        assert_eq!(zigzagp(u64::max_value() - 1), i64::max_value());
712        assert_eq!(zigzagp(u64::max_value()), i64::min_value());
713    }
714}