bincode/config/
int.rs

1use std::io::Write;
2use std::mem::size_of;
3
4use super::Options;
5use de::read::BincodeRead;
6use error::{ErrorKind, Result};
7
8pub trait IntEncoding {
9    /// Gets the size (in bytes) that a value would be serialized to.
10    fn u16_size(n: u16) -> u64;
11    /// Gets the size (in bytes) that a value would be serialized to.
12    fn u32_size(n: u32) -> u64;
13    /// Gets the size (in bytes) that a value would be serialized to.
14    fn u64_size(n: u64) -> u64;
15
16    /// Gets the size (in bytes) that a value would be serialized to.
17    fn i16_size(n: i16) -> u64;
18    /// Gets the size (in bytes) that a value would be serialized to.
19    fn i32_size(n: i32) -> u64;
20    /// Gets the size (in bytes) that a value would be serialized to.
21    fn i64_size(n: i64) -> u64;
22
23    #[inline(always)]
24    fn len_size(len: usize) -> u64 {
25        Self::u64_size(len as u64)
26    }
27
28    /// Serializes a sequence length.
29    #[inline(always)]
30    fn serialize_len<W: Write, O: Options>(
31        ser: &mut ::ser::Serializer<W, O>,
32        len: usize,
33    ) -> Result<()> {
34        Self::serialize_u64(ser, len as u64)
35    }
36
37    fn serialize_u16<W: Write, O: Options>(
38        ser: &mut ::ser::Serializer<W, O>,
39        val: u16,
40    ) -> Result<()>;
41
42    fn serialize_u32<W: Write, O: Options>(
43        ser: &mut ::ser::Serializer<W, O>,
44        val: u32,
45    ) -> Result<()>;
46
47    fn serialize_u64<W: Write, O: Options>(
48        ser: &mut ::ser::Serializer<W, O>,
49        val: u64,
50    ) -> Result<()>;
51
52    fn serialize_i16<W: Write, O: Options>(
53        ser: &mut ::ser::Serializer<W, O>,
54        val: i16,
55    ) -> Result<()>;
56
57    fn serialize_i32<W: Write, O: Options>(
58        ser: &mut ::ser::Serializer<W, O>,
59        val: i32,
60    ) -> Result<()>;
61
62    fn serialize_i64<W: Write, O: Options>(
63        ser: &mut ::ser::Serializer<W, O>,
64        val: i64,
65    ) -> Result<()>;
66
67    /// Deserializes a sequence length.
68    #[inline(always)]
69    fn deserialize_len<'de, R: BincodeRead<'de>, O: Options>(
70        de: &mut ::de::Deserializer<R, O>,
71    ) -> Result<usize> {
72        Self::deserialize_u64(de).and_then(cast_u64_to_usize)
73    }
74
75    fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
76        de: &mut ::de::Deserializer<R, O>,
77    ) -> Result<u16>;
78
79    fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
80        de: &mut ::de::Deserializer<R, O>,
81    ) -> Result<u32>;
82
83    fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
84        de: &mut ::de::Deserializer<R, O>,
85    ) -> Result<u64>;
86
87    fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
88        de: &mut ::de::Deserializer<R, O>,
89    ) -> Result<i16>;
90
91    fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
92        de: &mut ::de::Deserializer<R, O>,
93    ) -> Result<i32>;
94
95    fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
96        de: &mut ::de::Deserializer<R, O>,
97    ) -> Result<i64>;
98
99    serde_if_integer128! {
100        fn u128_size(v: u128) -> u64;
101        fn i128_size(v: i128) -> u64;
102        fn serialize_u128<W: Write, O: Options>(
103            ser: &mut ::Serializer<W, O>,
104            val: u128,
105        ) -> Result<()>;
106        fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
107            de: &mut ::Deserializer<R, O>,
108        ) -> Result<u128>;
109        fn serialize_i128<W: Write, O: Options>(
110            ser: &mut ::Serializer<W, O>,
111            val: i128,
112        ) -> Result<()>;
113        fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
114            de: &mut ::Deserializer<R, O>,
115        ) -> Result<i128>;
116    }
117}
118
119/// Fixed-size integer encoding.
120///
121/// * Fixed size integers are encoded directly
122/// * Enum discriminants are encoded as u32
123/// * Lengths and usize are encoded as u64
124#[derive(Copy, Clone)]
125pub struct FixintEncoding;
126
127/// Variable-size integer encoding (excepting [ui]8).
128///
129/// Encoding an unsigned integer v (of any type excepting u8) works as follows:
130///
131/// 1. If `u < 251`, encode it as a single byte with that value.
132/// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
133/// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`.
134/// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
135/// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a
136///   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 % 2 == 0 {
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 ::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 as u64)
238        }
239    }
240
241    fn deserialize_varint<'de, R: BincodeRead<'de>, O: Options>(
242        de: &mut ::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 % 2 == 0 {
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 ::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 ::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>(ser: &mut ::Serializer<W, O>, val: u16) -> Result<()> {
359        ser.serialize_literal_u16(val)
360    }
361    #[inline(always)]
362    fn serialize_u32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u32) -> Result<()> {
363        ser.serialize_literal_u32(val)
364    }
365    #[inline(always)]
366    fn serialize_u64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u64) -> Result<()> {
367        ser.serialize_literal_u64(val)
368    }
369
370    #[inline(always)]
371    fn serialize_i16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i16) -> Result<()> {
372        ser.serialize_literal_u16(val as u16)
373    }
374    #[inline(always)]
375    fn serialize_i32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i32) -> Result<()> {
376        ser.serialize_literal_u32(val as u32)
377    }
378    #[inline(always)]
379    fn serialize_i64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i64) -> Result<()> {
380        ser.serialize_literal_u64(val as u64)
381    }
382
383    #[inline(always)]
384    fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
385        de: &mut ::Deserializer<R, O>,
386    ) -> Result<u16> {
387        de.deserialize_literal_u16()
388    }
389    #[inline(always)]
390    fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
391        de: &mut ::Deserializer<R, O>,
392    ) -> Result<u32> {
393        de.deserialize_literal_u32()
394    }
395    #[inline(always)]
396    fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
397        de: &mut ::Deserializer<R, O>,
398    ) -> Result<u64> {
399        de.deserialize_literal_u64()
400    }
401
402    #[inline(always)]
403    fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
404        de: &mut ::Deserializer<R, O>,
405    ) -> Result<i16> {
406        Ok(de.deserialize_literal_u16()? as i16)
407    }
408    #[inline(always)]
409    fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
410        de: &mut ::Deserializer<R, O>,
411    ) -> Result<i32> {
412        Ok(de.deserialize_literal_u32()? as i32)
413    }
414    #[inline(always)]
415    fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
416        de: &mut ::Deserializer<R, O>,
417    ) -> Result<i64> {
418        Ok(de.deserialize_literal_u64()? as i64)
419    }
420
421    serde_if_integer128! {
422        #[inline(always)]
423        fn u128_size(_: u128) -> u64{
424            size_of::<u128>() as u64
425        }
426        #[inline(always)]
427        fn i128_size(_: i128) -> u64{
428            size_of::<i128>() as u64
429        }
430
431        #[inline(always)]
432        fn serialize_u128<W: Write, O: Options>(
433            ser: &mut ::Serializer<W, O>,
434            val: u128,
435        ) -> Result<()> {
436            ser.serialize_literal_u128(val)
437        }
438        #[inline(always)]
439        fn serialize_i128<W: Write, O: Options>(
440            ser: &mut ::Serializer<W, O>,
441            val: i128,
442        ) -> Result<()> {
443            ser.serialize_literal_u128(val as u128)
444        }
445        #[inline(always)]
446        fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
447            de: &mut ::Deserializer<R, O>,
448        ) -> Result<u128> {
449            de.deserialize_literal_u128()
450        }
451        #[inline(always)]
452        fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
453            de: &mut ::Deserializer<R, O>,
454        ) -> Result<i128> {
455            Ok(de.deserialize_literal_u128()? as i128)
456        }
457    }
458}
459
460impl IntEncoding for VarintEncoding {
461    #[inline(always)]
462    fn u16_size(n: u16) -> u64 {
463        Self::varint_size(n as u64)
464    }
465    #[inline(always)]
466    fn u32_size(n: u32) -> u64 {
467        Self::varint_size(n as u64)
468    }
469    #[inline(always)]
470    fn u64_size(n: u64) -> u64 {
471        Self::varint_size(n)
472    }
473
474    #[inline(always)]
475    fn i16_size(n: i16) -> u64 {
476        Self::varint_size(Self::zigzag_encode(n as i64))
477    }
478    #[inline(always)]
479    fn i32_size(n: i32) -> u64 {
480        Self::varint_size(Self::zigzag_encode(n as i64))
481    }
482    #[inline(always)]
483    fn i64_size(n: i64) -> u64 {
484        Self::varint_size(Self::zigzag_encode(n))
485    }
486
487    #[inline(always)]
488    fn serialize_u16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u16) -> Result<()> {
489        Self::serialize_varint(ser, val as u64)
490    }
491    #[inline(always)]
492    fn serialize_u32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u32) -> Result<()> {
493        Self::serialize_varint(ser, val as u64)
494    }
495    #[inline(always)]
496    fn serialize_u64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u64) -> Result<()> {
497        Self::serialize_varint(ser, val)
498    }
499
500    #[inline(always)]
501    fn serialize_i16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i16) -> Result<()> {
502        Self::serialize_varint(ser, Self::zigzag_encode(val as i64))
503    }
504    #[inline(always)]
505    fn serialize_i32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i32) -> Result<()> {
506        Self::serialize_varint(ser, Self::zigzag_encode(val as i64))
507    }
508    #[inline(always)]
509    fn serialize_i64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i64) -> Result<()> {
510        Self::serialize_varint(ser, Self::zigzag_encode(val))
511    }
512
513    #[inline(always)]
514    fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
515        de: &mut ::Deserializer<R, O>,
516    ) -> Result<u16> {
517        Self::deserialize_varint(de).and_then(cast_u64_to_u16)
518    }
519    #[inline(always)]
520    fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
521        de: &mut ::Deserializer<R, O>,
522    ) -> Result<u32> {
523        Self::deserialize_varint(de).and_then(cast_u64_to_u32)
524    }
525    #[inline(always)]
526    fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
527        de: &mut ::Deserializer<R, O>,
528    ) -> Result<u64> {
529        Self::deserialize_varint(de)
530    }
531
532    #[inline(always)]
533    fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
534        de: &mut ::Deserializer<R, O>,
535    ) -> Result<i16> {
536        Self::deserialize_varint(de)
537            .map(Self::zigzag_decode)
538            .and_then(cast_i64_to_i16)
539    }
540    #[inline(always)]
541    fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
542        de: &mut ::Deserializer<R, O>,
543    ) -> Result<i32> {
544        Self::deserialize_varint(de)
545            .map(Self::zigzag_decode)
546            .and_then(cast_i64_to_i32)
547    }
548    #[inline(always)]
549    fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
550        de: &mut ::Deserializer<R, O>,
551    ) -> Result<i64> {
552        Self::deserialize_varint(de).map(Self::zigzag_decode)
553    }
554
555    serde_if_integer128! {
556        #[inline(always)]
557        fn u128_size(n: u128) -> u64 {
558            Self::varint128_size(n)
559        }
560        #[inline(always)]
561        fn i128_size(n: i128) -> u64 {
562            Self::varint128_size(Self::zigzag128_encode(n))
563        }
564        #[inline(always)]
565        fn serialize_u128<W: Write, O: Options>(
566            ser: &mut ::Serializer<W, O>,
567            val: u128,
568        ) -> Result<()> {
569            Self::serialize_varint128(ser, val)
570        }
571        #[inline(always)]
572        fn serialize_i128<W: Write, O: Options>(
573            ser: &mut ::Serializer<W, O>,
574            val: i128,
575        ) -> Result<()> {
576            Self::serialize_varint128(ser, Self::zigzag128_encode(val))
577        }
578        #[inline(always)]
579        fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
580            de: &mut ::Deserializer<R, O>,
581        ) -> Result<u128> {
582            Self::deserialize_varint128(de)
583        }
584        #[inline(always)]
585        fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
586            de: &mut ::Deserializer<R, O>,
587        ) -> Result<i128> {
588            Self::deserialize_varint128(de).map(Self::zigzag128_decode)
589        }
590    }
591}
592
593fn cast_u64_to_usize(n: u64) -> Result<usize> {
594    if n <= usize::max_value() as u64 {
595        Ok(n as usize)
596    } else {
597        Err(Box::new(ErrorKind::Custom(format!(
598            "Invalid size {}: sizes must fit in a usize (0 to {})",
599            n,
600            usize::max_value()
601        ))))
602    }
603}
604fn cast_u64_to_u32(n: u64) -> Result<u32> {
605    if n <= u32::max_value() as u64 {
606        Ok(n as u32)
607    } else {
608        Err(Box::new(ErrorKind::Custom(format!(
609            "Invalid u32 {}: you may have a version disagreement?",
610            n,
611        ))))
612    }
613}
614fn cast_u64_to_u16(n: u64) -> Result<u16> {
615    if n <= u16::max_value() as u64 {
616        Ok(n as u16)
617    } else {
618        Err(Box::new(ErrorKind::Custom(format!(
619            "Invalid u16 {}: you may have a version disagreement?",
620            n,
621        ))))
622    }
623}
624
625fn cast_i64_to_i32(n: i64) -> Result<i32> {
626    if n <= i32::max_value() as i64 && n >= i32::min_value() as i64 {
627        Ok(n as i32)
628    } else {
629        Err(Box::new(ErrorKind::Custom(format!(
630            "Invalid i32 {}: you may have a version disagreement?",
631            n,
632        ))))
633    }
634}
635
636fn cast_i64_to_i16(n: i64) -> Result<i16> {
637    if n <= i16::max_value() as i64 && n >= i16::min_value() as i64 {
638        Ok(n as i16)
639    } else {
640        Err(Box::new(ErrorKind::Custom(format!(
641            "Invalid i16 {}: you may have a version disagreement?",
642            n,
643        ))))
644    }
645}
646
647#[cfg(test)]
648mod test {
649    use super::VarintEncoding;
650
651    #[test]
652    fn test_zigzag_encode() {
653        let zigzag = VarintEncoding::zigzag_encode;
654
655        assert_eq!(zigzag(0), 0);
656        for x in 1..512 {
657            assert_eq!(zigzag(x), (x as u64) * 2);
658            assert_eq!(zigzag(-x), (x as u64) * 2 - 1);
659        }
660    }
661
662    #[test]
663    fn test_zigzag_decode() {
664        // zigzag'
665        let zigzagp = VarintEncoding::zigzag_decode;
666        for x in (0..512).map(|x| x * 2) {
667            assert_eq!(zigzagp(x), x as i64 / 2);
668            assert_eq!(zigzagp(x + 1), -(x as i64) / 2 - 1);
669        }
670    }
671
672    #[test]
673    fn test_zigzag_edge_cases() {
674        let (zigzag, zigzagp) = (VarintEncoding::zigzag_encode, VarintEncoding::zigzag_decode);
675
676        assert_eq!(zigzag(i64::max_value()), u64::max_value() - 1);
677        assert_eq!(zigzag(i64::min_value()), u64::max_value());
678
679        assert_eq!(zigzagp(u64::max_value() - 1), i64::max_value());
680        assert_eq!(zigzagp(u64::max_value()), i64::min_value());
681    }
682}