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 fn u16_size(n: u16) -> u64;
12 fn u32_size(n: u32) -> u64;
14 fn u64_size(n: u64) -> u64;
16
17 fn i16_size(n: i16) -> u64;
19 fn i32_size(n: i32) -> u64;
21 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 #[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 #[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#[derive(Copy, Clone)]
126pub struct FixintEncoding;
127
128#[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 !(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 (n / 2) as i64
212 } else {
213 !(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 #[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 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}