1use arrayvec::ArrayVec;
18
19use crate::{
20 alloc::vec::Vec,
21 codec::{Decode, Encode, EncodeAsRef, Input, Output},
22 encode_like::EncodeLike,
23 DecodeWithMemTracking, Error,
24};
25
26#[cfg(feature = "fuzz")]
27use arbitrary::Arbitrary;
28
29struct ArrayVecWrapper<const N: usize>(ArrayVec<u8, N>);
30
31impl<const N: usize> Output for ArrayVecWrapper<N> {
32 fn write(&mut self, bytes: &[u8]) {
33 let old_len = self.0.len();
34 let new_len = old_len + bytes.len();
35
36 assert!(new_len <= self.0.capacity());
37 unsafe {
38 self.0.set_len(new_len);
39 }
40
41 self.0[old_len..new_len].copy_from_slice(bytes);
42 }
43
44 fn push_byte(&mut self, byte: u8) {
45 self.0.push(byte);
46 }
47}
48
49pub trait CompactLen<T> {
51 fn compact_len(val: &T) -> usize;
53}
54
55#[derive(Eq, PartialEq, Clone, Copy, Ord, PartialOrd)]
57#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
58pub struct Compact<T>(pub T);
59
60impl<T> From<T> for Compact<T> {
61 fn from(x: T) -> Compact<T> {
62 Compact(x)
63 }
64}
65
66impl<'a, T: Copy> From<&'a T> for Compact<T> {
67 fn from(x: &'a T) -> Compact<T> {
68 Compact(*x)
69 }
70}
71
72pub trait CompactAs: From<Compact<Self>> {
74 type As;
76
77 fn encode_as(&self) -> &Self::As;
79
80 fn decode_from(_: Self::As) -> Result<Self, Error>;
82}
83
84impl<T> EncodeLike for Compact<T> where for<'a> CompactRef<'a, T>: Encode {}
85
86impl<T> Encode for Compact<T>
87where
88 for<'a> CompactRef<'a, T>: Encode,
89{
90 fn size_hint(&self) -> usize {
91 CompactRef(&self.0).size_hint()
92 }
93
94 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
95 CompactRef(&self.0).encode_to(dest)
96 }
97
98 fn encode(&self) -> Vec<u8> {
99 CompactRef(&self.0).encode()
100 }
101
102 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
103 CompactRef(&self.0).using_encoded(f)
104 }
105}
106
107impl<T> EncodeLike for CompactRef<'_, T>
108where
109 T: CompactAs,
110 for<'b> CompactRef<'b, T::As>: Encode,
111{
112}
113
114impl<T> Encode for CompactRef<'_, T>
115where
116 T: CompactAs,
117 for<'b> CompactRef<'b, T::As>: Encode,
118{
119 fn size_hint(&self) -> usize {
120 CompactRef(self.0.encode_as()).size_hint()
121 }
122
123 fn encode_to<Out: Output + ?Sized>(&self, dest: &mut Out) {
124 CompactRef(self.0.encode_as()).encode_to(dest)
125 }
126
127 fn encode(&self) -> Vec<u8> {
128 CompactRef(self.0.encode_as()).encode()
129 }
130
131 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
132 CompactRef(self.0.encode_as()).using_encoded(f)
133 }
134}
135
136impl<T> Decode for Compact<T>
137where
138 T: CompactAs,
139 Compact<T::As>: Decode,
140{
141 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
142 let as_ = Compact::<T::As>::decode(input)?;
143 Ok(Compact(<T as CompactAs>::decode_from(as_.0)?))
144 }
145}
146
147impl<T> DecodeWithMemTracking for Compact<T>
148where
149 T: CompactAs,
150 Compact<T::As>: DecodeWithMemTracking,
151{
152}
153
154macro_rules! impl_from_compact {
155 ( $( $ty:ty ),* ) => {
156 $(
157 impl From<Compact<$ty>> for $ty {
158 fn from(x: Compact<$ty>) -> $ty { x.0 }
159 }
160 )*
161 }
162}
163
164impl_from_compact! { (), u8, u16, u32, u64, u128 }
165
166#[derive(Eq, PartialEq, Clone, Copy)]
168pub struct CompactRef<'a, T>(pub &'a T);
169
170impl<'a, T> From<&'a T> for CompactRef<'a, T> {
171 fn from(x: &'a T) -> Self {
172 CompactRef(x)
173 }
174}
175
176impl<T> core::fmt::Debug for Compact<T>
177where
178 T: core::fmt::Debug,
179{
180 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
181 self.0.fmt(f)
182 }
183}
184
185#[cfg(feature = "serde")]
186impl<T> serde::Serialize for Compact<T>
187where
188 T: serde::Serialize,
189{
190 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
191 where
192 S: serde::Serializer,
193 {
194 T::serialize(&self.0, serializer)
195 }
196}
197
198#[cfg(feature = "serde")]
199impl<'de, T> serde::Deserialize<'de> for Compact<T>
200where
201 T: serde::Deserialize<'de>,
202{
203 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
204 where
205 D: serde::Deserializer<'de>,
206 {
207 T::deserialize(deserializer).map(Compact)
208 }
209}
210
211pub trait HasCompact: Sized {
213 type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From<Self> + Into<Self>;
215}
216
217impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact<T>
218where
219 CompactRef<'a, T>: Encode + From<&'a T>,
220{
221 type RefType = CompactRef<'a, T>;
222}
223
224impl<T: 'static> HasCompact for T
225where
226 Compact<T>: for<'a> EncodeAsRef<'a, T> + Decode + From<Self> + Into<Self>,
227{
228 type Type = Compact<T>;
229}
230
231impl Encode for CompactRef<'_, ()> {
232 fn encode_to<W: Output + ?Sized>(&self, _dest: &mut W) {}
233
234 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
235 f(&[])
236 }
237
238 fn encode(&self) -> Vec<u8> {
239 Vec::new()
240 }
241}
242
243struct WrappedPrimitive<T>(T);
244
245impl<T> CompactLen<T> for WrappedPrimitive<T>
246where
247 T: Copy + Into<u64>,
248{
249 fn compact_len(val: &T) -> usize {
250 let x = (*val).into();
251 1 + if x == 0 {
252 0
253 } else if let Some(l) = (0..8).find(|l| 2_u64.pow(7 * l) <= x && x < 2_u64.pow(7 * (l + 1)))
254 {
255 l
256 } else {
257 8
258 } as usize
259 }
260}
261
262impl<T> Encode for WrappedPrimitive<T>
263where
264 T: Copy + Into<u64>,
265{
266 fn size_hint(&self) -> usize {
267 Self::compact_len(&self.0)
268 }
269
270 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
271 let x = self.0.into();
272 if x == 0 {
273 dest.push_byte(0);
274 } else if let Some(l) = (0..8).find(|l| 2_u64.pow(7 * l) <= x && x < 2_u64.pow(7 * (l + 1)))
275 {
276 dest.push_byte((2_u64.pow(8) - 2_u64.pow(8 - l) + (x / 2_u64.pow(8 * l))) as u8);
277 dest.write(&(x % 2_u64.pow(8 * l)).to_le_bytes()[..l as usize]);
278 } else {
279 dest.push_byte((2_u64.pow(8) - 1) as u8);
280 dest.write(&x.to_le_bytes());
281 }
282 }
283
284 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
285 let mut r = ArrayVecWrapper(ArrayVec::<u8, 9>::new());
286 self.encode_to(&mut r);
287 f(&r.0)
288 }
289}
290
291impl<T> Decode for WrappedPrimitive<T>
292where
293 T: Copy + TryFrom<u64>,
294{
295 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
296 const OUT_OF_RANGE: &str = "Out of range";
297 let v = match input.read_byte()? {
298 0 => 0,
299 0xff => u64::decode(input)?,
300 b => {
301 let l = (0..8).find(|&i| (b & (0b1000_0000 >> i)) == 0).unwrap();
302 let mut buf = [0u8; 8];
303 input.read(&mut buf[..l])?;
304 let rem = (b & ((1 << (7 - l)) - 1)) as u64;
305 u64::from_le_bytes(buf) + (rem << (8 * l))
306 },
307 };
308 let v = T::try_from(v).map_err(|_| Error::from(OUT_OF_RANGE))?;
309 Ok(Self(v))
310 }
311}
312
313impl Encode for CompactRef<'_, u8> {
314 fn size_hint(&self) -> usize {
315 WrappedPrimitive(*self.0).size_hint()
316 }
317
318 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
319 WrappedPrimitive(*self.0).encode_to(dest)
320 }
321
322 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
323 WrappedPrimitive(*self.0).using_encoded(f)
324 }
325}
326
327impl CompactLen<u8> for Compact<u8> {
328 fn compact_len(val: &u8) -> usize {
329 WrappedPrimitive::<u8>::compact_len(val)
330 }
331}
332
333impl Encode for CompactRef<'_, u16> {
334 fn size_hint(&self) -> usize {
335 WrappedPrimitive(*self.0).size_hint()
336 }
337
338 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
339 WrappedPrimitive(*self.0).encode_to(dest)
340 }
341
342 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
343 WrappedPrimitive(*self.0).using_encoded(f)
344 }
345}
346
347impl CompactLen<u16> for Compact<u16> {
348 fn compact_len(val: &u16) -> usize {
349 WrappedPrimitive::<u16>::compact_len(val)
350 }
351}
352
353impl Encode for CompactRef<'_, u32> {
354 fn size_hint(&self) -> usize {
355 WrappedPrimitive(*self.0).size_hint()
356 }
357
358 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
359 WrappedPrimitive(*self.0).encode_to(dest)
360 }
361
362 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
363 WrappedPrimitive(*self.0).using_encoded(f)
364 }
365}
366
367impl CompactLen<u32> for Compact<u32> {
368 fn compact_len(val: &u32) -> usize {
369 WrappedPrimitive::<u32>::compact_len(val)
370 }
371}
372
373impl Encode for CompactRef<'_, u64> {
374 fn size_hint(&self) -> usize {
375 WrappedPrimitive(*self.0).size_hint()
376 }
377
378 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
379 WrappedPrimitive(*self.0).encode_to(dest)
380 }
381
382 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
383 WrappedPrimitive(*self.0).using_encoded(f)
384 }
385}
386
387impl CompactLen<u64> for Compact<u64> {
388 fn compact_len(val: &u64) -> usize {
389 WrappedPrimitive::<u64>::compact_len(val)
390 }
391}
392
393impl Encode for CompactRef<'_, u128> {
394 fn size_hint(&self) -> usize {
395 Compact::<u128>::compact_len(self.0)
396 }
397
398 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
399 let l = (*self.0 & u64::MAX as u128) as u64;
400 let h = (*self.0 >> 64) as u64;
401 WrappedPrimitive::<u64>::encode_to(&WrappedPrimitive(l), dest);
402 WrappedPrimitive::<u64>::encode_to(&WrappedPrimitive(h), dest);
403 }
404}
405
406impl CompactLen<u128> for Compact<u128> {
407 fn compact_len(val: &u128) -> usize {
408 let l = (*val & u64::MAX as u128) as u64;
409 let h = (*val >> 64) as u64;
410 Compact::compact_len(&l) + Compact::compact_len(&h)
411 }
412}
413
414impl Decode for Compact<()> {
415 fn decode<I: Input>(_input: &mut I) -> Result<Self, Error> {
416 Ok(Compact(()))
417 }
418}
419
420impl DecodeWithMemTracking for Compact<()> {}
421
422impl Decode for Compact<u8> {
423 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
424 WrappedPrimitive::<u8>::decode(input).map(|w| Compact(w.0))
425 }
426}
427
428impl DecodeWithMemTracking for Compact<u8> {}
429
430impl Decode for Compact<u16> {
431 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
432 WrappedPrimitive::<u16>::decode(input).map(|w| Compact(w.0))
433 }
434}
435
436impl DecodeWithMemTracking for Compact<u16> {}
437
438impl Decode for Compact<u32> {
439 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
440 WrappedPrimitive::<u32>::decode(input).map(|w| Compact(w.0))
441 }
442}
443
444impl DecodeWithMemTracking for Compact<u32> {}
445
446impl Decode for Compact<u64> {
447 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
448 WrappedPrimitive::<u64>::decode(input).map(|w| Compact(w.0))
449 }
450}
451
452impl DecodeWithMemTracking for Compact<u64> {}
453
454impl Decode for Compact<u128> {
455 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
456 let l = WrappedPrimitive::<u64>::decode(input).map(|w| Compact(w.0))?.0;
457 let h = WrappedPrimitive::<u64>::decode(input).map(|w| Compact(w.0))?.0;
458 Ok(Compact((h as u128) << 64 | l as u128))
459 }
460}
461
462impl DecodeWithMemTracking for Compact<u128> {}
463
464#[cfg(test)]
465mod tests {
466 use super::*;
467
468 #[test]
469 fn compact_128_encoding_works() {
470 let tests = [
471 (0u128, 2),
472 (63, 2),
473 (64, 2),
474 (16383, 3),
475 (16384, 4),
476 (1073741823, 6),
477 (1073741824, 6),
478 ((1 << 32) - 1, 6),
479 (1 << 32, 6),
480 (1 << 40, 7), (1 << 48, 8),
482 ((1 << 56) - 1, 9),
483 (1 << 56, 10),
484 ((1 << 64) - 1, 10),
485 (1 << 64, 2),
486 (1 << 72, 3),
487 (1 << 80, 4),
488 (1 << 88, 5),
489 (1 << 96, 6),
490 (1 << 104, 7), (1 << 112, 8),
492 ((1 << 120) - 1, 17),
493 (1 << 120, 10),
494 (u128::MAX, 18),
495 ];
496 for &(n, l) in &tests {
497 let encoded = Compact(n).encode();
498 println!("{}", hex::encode(&encoded));
499 assert_eq!(encoded.len(), l);
500 assert_eq!(Compact::compact_len(&n), l);
501 assert_eq!(<Compact<u128>>::decode(&mut &encoded[..]).unwrap().0, n);
502 }
503 }
504
505 #[test]
506 fn compact_64_encoding_works() {
507 let tests = [
508 (0u64, 1usize),
509 (63, 1),
510 (64, 1),
511 (16383, 2),
512 (16384, 3),
513 (1073741823, 5),
514 (1073741824, 5),
515 ((1 << 32) - 1, 5),
516 (1 << 32, 5),
517 (1 << 40, 6),
518 (1 << 48, 7),
519 ((1 << 56) - 1, 8),
520 (1 << 56, 9),
521 (u64::MAX, 9),
522 ];
523 for &(n, l) in &tests {
524 let encoded = Compact(n).encode();
525 assert_eq!(encoded.len(), l);
526 assert_eq!(Compact::compact_len(&n), l);
527 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
528 }
529 }
530
531 #[test]
532 fn compact_32_encoding_works() {
533 let tests = [
534 (0u32, 1usize),
535 (63, 1),
536 (64, 1),
537 (16383, 2),
538 (16384, 3),
539 (1073741823, 5),
540 (1073741824, 5),
541 (u32::MAX, 5),
542 ];
543 for &(n, l) in &tests {
544 let encoded = Compact(n).encode();
545 assert_eq!(encoded.len(), l);
546 assert_eq!(Compact::compact_len(&n), l);
547 assert_eq!(<Compact<u32>>::decode(&mut &encoded[..]).unwrap().0, n);
548 }
549 }
550
551 #[test]
552 fn compact_16_encoding_works() {
553 let tests = [(0u16, 1usize), (63, 1), (64, 1), (16383, 2), (16384, 3), (65535, 3)];
554 for &(n, l) in &tests {
555 let encoded = Compact(n).encode();
556 assert_eq!(encoded.len(), l);
557 assert_eq!(Compact::compact_len(&n), l);
558 assert_eq!(<Compact<u16>>::decode(&mut &encoded[..]).unwrap().0, n);
559 }
560 assert!(<Compact<u16>>::decode(&mut &Compact(65536u32).encode()[..]).is_err());
561 }
562
563 #[test]
564 fn compact_8_encoding_works() {
565 let tests = [(0u8, 1usize), (63, 1), (64, 1), (255, 2)];
566 for &(n, l) in &tests {
567 let encoded = Compact(n).encode();
568 assert_eq!(encoded.len(), l);
569 assert_eq!(Compact::compact_len(&n), l);
570 assert_eq!(<Compact<u8>>::decode(&mut &encoded[..]).unwrap().0, n);
571 }
572 assert!(<Compact<u8>>::decode(&mut &Compact(256u32).encode()[..]).is_err());
573 }
574
575 fn hexify(bytes: &[u8]) -> String {
576 bytes
577 .iter()
578 .map(|ref b| format!("{:02x}", b))
579 .collect::<Vec<String>>()
580 .join(" ")
581 }
582
583 #[test]
584 fn compact_integers_encoded_as_expected() {
585 let tests = [
586 (0u64, "00"),
587 (63, "3f"),
588 (64, "40"),
589 (16383, "bf ff"),
590 (16384, "c0 00 40"),
591 (1073741823, "f0 ff ff ff 3f"),
592 (1073741824, "f0 00 00 00 40"),
593 ((1 << 32) - 1, "f0 ff ff ff ff"),
594 (1 << 32, "f1 00 00 00 00"),
595 (1 << 40, "f9 00 00 00 00 00"),
596 (1 << 48, "fd 00 00 00 00 00 00"),
597 ((1 << 56) - 1, "fe ff ff ff ff ff ff ff"),
598 (1 << 56, "ff 00 00 00 00 00 00 00 01"),
599 (u64::MAX, "ff ff ff ff ff ff ff ff ff"),
600 ];
601 for &(n, s) in &tests {
602 let encoded = Compact(n).encode();
604 assert_eq!(hexify(&encoded), s);
605 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
606
607 if n <= u32::MAX as u64 {
609 assert_eq!(<Compact<u32>>::decode(&mut &encoded[..]).unwrap().0, n as u32);
610 let encoded = Compact(n as u32).encode();
611 assert_eq!(hexify(&encoded), s);
612 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
613 }
614 if n <= u16::MAX as u64 {
615 assert_eq!(<Compact<u16>>::decode(&mut &encoded[..]).unwrap().0, n as u16);
616 let encoded = Compact(n as u16).encode();
617 assert_eq!(hexify(&encoded), s);
618 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
619 }
620 if n <= u8::MAX as u64 {
621 assert_eq!(<Compact<u8>>::decode(&mut &encoded[..]).unwrap().0, n as u8);
622 let encoded = Compact(n as u8).encode();
623 assert_eq!(hexify(&encoded), s);
624 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
625 }
626 }
627 }
628
629 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
630 #[derive(PartialEq, Eq, Clone)]
631 struct Wrapper(u8);
632
633 impl CompactAs for Wrapper {
634 type As = u8;
635 fn encode_as(&self) -> &u8 {
636 &self.0
637 }
638 fn decode_from(x: u8) -> Result<Wrapper, Error> {
639 Ok(Wrapper(x))
640 }
641 }
642
643 impl From<Compact<Wrapper>> for Wrapper {
644 fn from(x: Compact<Wrapper>) -> Wrapper {
645 x.0
646 }
647 }
648
649 #[test]
650 fn compact_as_8_encoding_works() {
651 let tests = [(0u8, 1usize), (63, 1), (64, 1), (255, 2)];
652 for &(n, l) in &tests {
653 let compact: Compact<Wrapper> = Wrapper(n).into();
654 let encoded = compact.encode();
655 assert_eq!(encoded.len(), l);
656 assert_eq!(Compact::compact_len(&n), l);
657 let decoded = <Compact<Wrapper>>::decode(&mut &encoded[..]).unwrap();
658 let wrapper: Wrapper = decoded.into();
659 assert_eq!(wrapper, Wrapper(n));
660 }
661 }
662
663 struct WithCompact<T: HasCompact> {
664 _data: T,
665 }
666
667 #[test]
668 fn compact_as_has_compact() {
669 let _data = WithCompact { _data: Wrapper(1) };
670 }
671
672 #[test]
673 fn compact_using_encoded_arrayvec_size() {
674 Compact(u8::MAX).using_encoded(|_| {});
675 Compact(u16::MAX).using_encoded(|_| {});
676 Compact(u32::MAX).using_encoded(|_| {});
677 Compact(u64::MAX).using_encoded(|_| {});
678 Compact(u128::MAX).using_encoded(|_| {});
679
680 CompactRef(&u8::MAX).using_encoded(|_| {});
681 CompactRef(&u16::MAX).using_encoded(|_| {});
682 CompactRef(&u32::MAX).using_encoded(|_| {});
683 CompactRef(&u64::MAX).using_encoded(|_| {});
684 CompactRef(&u128::MAX).using_encoded(|_| {});
685 }
686
687 #[test]
688 #[should_panic]
689 fn array_vec_output_oob() {
690 let mut v = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
691 v.write(&[1, 2, 3, 4, 5]);
692 }
693
694 #[test]
695 fn array_vec_output() {
696 let mut v = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
697 v.write(&[1, 2, 3, 4]);
698 }
699
700 #[test]
701 fn compact_u64_test() {
702 for a in [
703 u64::MAX,
704 u64::MAX - 1,
705 u64::MAX << 8,
706 (u64::MAX << 8) - 1,
707 u64::MAX << 16,
708 (u64::MAX << 16) - 1,
709 ]
710 .iter()
711 {
712 let e = Compact::<u64>::encode(&Compact(*a));
713 let d = Compact::<u64>::decode(&mut &e[..]).unwrap().0;
714 assert_eq!(*a, d);
715 }
716 }
717
718 #[test]
719 fn compact_u128_test() {
720 for a in [u64::MAX as u128, (u64::MAX - 10) as u128, u128::MAX, u128::MAX - 10].iter() {
721 let e = Compact::<u128>::encode(&Compact(*a));
722 let d = Compact::<u128>::decode(&mut &e[..]).unwrap().0;
723 assert_eq!(*a, d);
724 }
725 }
726
727 macro_rules! quick_check_roundtrip {
728 ( $( $ty:ty : $test:ident ),* ) => {
729 $(
730 quickcheck::quickcheck! {
731 fn $test(v: $ty) -> bool {
732 let encoded = Compact(v).encode();
733 let deencoded = <Compact<$ty>>::decode(&mut &encoded[..]).unwrap().0;
734
735 v == deencoded
736 }
737 }
738 )*
739 }
740 }
741
742 quick_check_roundtrip! {
743 u8: u8_roundtrip,
744 u16: u16_roundtrip,
745 u32 : u32_roundtrip,
746 u64 : u64_roundtrip,
747 u128 : u128_roundtrip
748 }
749}