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}
683