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 {
254 (0..8)
255 .find(|l| 2_u64.pow(7 * l) <= x && x < 2_u64.pow(7 * (l + 1)))
256 .unwrap_or(8)
257 } as usize
258 }
259}
260
261impl<T> Encode for WrappedPrimitive<T>
262where
263 T: Copy + Into<u64>,
264{
265 fn size_hint(&self) -> usize {
266 Self::compact_len(&self.0)
267 }
268
269 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
270 let x = self.0.into();
271 if x == 0 {
272 dest.push_byte(0);
273 } else if let Some(l) = (0..8).find(|l| 2_u64.pow(7 * l) <= x && x < 2_u64.pow(7 * (l + 1)))
274 {
275 dest.push_byte((2_u64.pow(8) - 2_u64.pow(8 - l) + (x / 2_u64.pow(8 * l))) as u8);
276 dest.write(&(x % 2_u64.pow(8 * l)).to_le_bytes()[..l as usize]);
277 } else {
278 dest.push_byte((2_u64.pow(8) - 1) as u8);
279 dest.write(&x.to_le_bytes());
280 }
281 }
282
283 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
284 let mut r = ArrayVecWrapper(ArrayVec::<u8, 9>::new());
285 self.encode_to(&mut r);
286 f(&r.0)
287 }
288}
289
290impl<T> Decode for WrappedPrimitive<T>
291where
292 T: Copy + TryFrom<u64>,
293{
294 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
295 const OUT_OF_RANGE: &str = "Out of range";
296 let v = match input.read_byte()? {
297 0 => 0,
298 0xff => u64::decode(input)?,
299 b => {
300 let l = (0..8).find(|&i| (b & (0b1000_0000 >> i)) == 0).unwrap();
301 let mut buf = [0u8; 8];
302 input.read(&mut buf[..l])?;
303 let rem = (b & ((1 << (7 - l)) - 1)) as u64;
304 u64::from_le_bytes(buf) + (rem << (8 * l))
305 },
306 };
307 let v = T::try_from(v).map_err(|_| Error::from(OUT_OF_RANGE))?;
308 Ok(Self(v))
309 }
310}
311
312impl Encode for CompactRef<'_, u8> {
313 fn size_hint(&self) -> usize {
314 WrappedPrimitive(*self.0).size_hint()
315 }
316
317 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
318 WrappedPrimitive(*self.0).encode_to(dest)
319 }
320
321 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
322 WrappedPrimitive(*self.0).using_encoded(f)
323 }
324}
325
326impl CompactLen<u8> for Compact<u8> {
327 fn compact_len(val: &u8) -> usize {
328 WrappedPrimitive::<u8>::compact_len(val)
329 }
330}
331
332impl Encode for CompactRef<'_, u16> {
333 fn size_hint(&self) -> usize {
334 WrappedPrimitive(*self.0).size_hint()
335 }
336
337 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
338 WrappedPrimitive(*self.0).encode_to(dest)
339 }
340
341 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
342 WrappedPrimitive(*self.0).using_encoded(f)
343 }
344}
345
346impl CompactLen<u16> for Compact<u16> {
347 fn compact_len(val: &u16) -> usize {
348 WrappedPrimitive::<u16>::compact_len(val)
349 }
350}
351
352impl Encode for CompactRef<'_, u32> {
353 fn size_hint(&self) -> usize {
354 WrappedPrimitive(*self.0).size_hint()
355 }
356
357 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
358 WrappedPrimitive(*self.0).encode_to(dest)
359 }
360
361 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
362 WrappedPrimitive(*self.0).using_encoded(f)
363 }
364}
365
366impl CompactLen<u32> for Compact<u32> {
367 fn compact_len(val: &u32) -> usize {
368 WrappedPrimitive::<u32>::compact_len(val)
369 }
370}
371
372impl Encode for CompactRef<'_, u64> {
373 fn size_hint(&self) -> usize {
374 WrappedPrimitive(*self.0).size_hint()
375 }
376
377 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
378 WrappedPrimitive(*self.0).encode_to(dest)
379 }
380
381 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
382 WrappedPrimitive(*self.0).using_encoded(f)
383 }
384}
385
386impl CompactLen<u64> for Compact<u64> {
387 fn compact_len(val: &u64) -> usize {
388 WrappedPrimitive::<u64>::compact_len(val)
389 }
390}
391
392impl Encode for CompactRef<'_, u128> {
393 fn size_hint(&self) -> usize {
394 Compact::<u128>::compact_len(self.0)
395 }
396
397 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
398 let l = (*self.0 & u64::MAX as u128) as u64;
399 let h = (*self.0 >> 64) as u64;
400 WrappedPrimitive::<u64>::encode_to(&WrappedPrimitive(l), dest);
401 WrappedPrimitive::<u64>::encode_to(&WrappedPrimitive(h), dest);
402 }
403}
404
405impl CompactLen<u128> for Compact<u128> {
406 fn compact_len(val: &u128) -> usize {
407 let l = (*val & u64::MAX as u128) as u64;
408 let h = (*val >> 64) as u64;
409 Compact::compact_len(&l) + Compact::compact_len(&h)
410 }
411}
412
413impl Decode for Compact<()> {
414 fn decode<I: Input>(_input: &mut I) -> Result<Self, Error> {
415 Ok(Compact(()))
416 }
417}
418
419impl DecodeWithMemTracking for Compact<()> {}
420
421impl Decode for Compact<u8> {
422 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
423 WrappedPrimitive::<u8>::decode(input).map(|w| Compact(w.0))
424 }
425}
426
427impl DecodeWithMemTracking for Compact<u8> {}
428
429impl Decode for Compact<u16> {
430 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
431 WrappedPrimitive::<u16>::decode(input).map(|w| Compact(w.0))
432 }
433}
434
435impl DecodeWithMemTracking for Compact<u16> {}
436
437impl Decode for Compact<u32> {
438 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
439 WrappedPrimitive::<u32>::decode(input).map(|w| Compact(w.0))
440 }
441}
442
443impl DecodeWithMemTracking for Compact<u32> {}
444
445impl Decode for Compact<u64> {
446 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
447 WrappedPrimitive::<u64>::decode(input).map(|w| Compact(w.0))
448 }
449}
450
451impl DecodeWithMemTracking for Compact<u64> {}
452
453impl Decode for Compact<u128> {
454 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
455 let l = WrappedPrimitive::<u64>::decode(input).map(|w| Compact(w.0))?.0;
456 let h = WrappedPrimitive::<u64>::decode(input).map(|w| Compact(w.0))?.0;
457 Ok(Compact((h as u128) << 64 | l as u128))
458 }
459}
460
461impl DecodeWithMemTracking for Compact<u128> {}
462
463#[cfg(test)]
464mod tests {
465 use super::*;
466
467 #[test]
468 fn compact_128_encoding_works() {
469 let tests = [
470 (0u128, 2),
471 (63, 2),
472 (64, 2),
473 (16383, 3),
474 (16384, 4),
475 (1073741823, 6),
476 (1073741824, 6),
477 ((1 << 32) - 1, 6),
478 (1 << 32, 6),
479 (1 << 40, 7), (1 << 48, 8),
481 ((1 << 56) - 1, 9),
482 (1 << 56, 10),
483 ((1 << 64) - 1, 10),
484 (1 << 64, 2),
485 (1 << 72, 3),
486 (1 << 80, 4),
487 (1 << 88, 5),
488 (1 << 96, 6),
489 (1 << 104, 7), (1 << 112, 8),
491 ((1 << 120) - 1, 17),
492 (1 << 120, 10),
493 (u128::MAX, 18),
494 ];
495 for &(n, l) in &tests {
496 let encoded = Compact(n).encode();
497 println!("{}", hex::encode(&encoded));
498 assert_eq!(encoded.len(), l);
499 assert_eq!(Compact::compact_len(&n), l);
500 assert_eq!(<Compact<u128>>::decode(&mut &encoded[..]).unwrap().0, n);
501 }
502 }
503
504 #[test]
505 fn compact_64_encoding_works() {
506 let tests = [
507 (0u64, 1usize),
508 (63, 1),
509 (64, 1),
510 (16383, 2),
511 (16384, 3),
512 (1073741823, 5),
513 (1073741824, 5),
514 ((1 << 32) - 1, 5),
515 (1 << 32, 5),
516 (1 << 40, 6),
517 (1 << 48, 7),
518 ((1 << 56) - 1, 8),
519 (1 << 56, 9),
520 (u64::MAX, 9),
521 ];
522 for &(n, l) in &tests {
523 let encoded = Compact(n).encode();
524 assert_eq!(encoded.len(), l);
525 assert_eq!(Compact::compact_len(&n), l);
526 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
527 }
528 }
529
530 #[test]
531 fn compact_32_encoding_works() {
532 let tests = [
533 (0u32, 1usize),
534 (63, 1),
535 (64, 1),
536 (16383, 2),
537 (16384, 3),
538 (1073741823, 5),
539 (1073741824, 5),
540 (u32::MAX, 5),
541 ];
542 for &(n, l) in &tests {
543 let encoded = Compact(n).encode();
544 assert_eq!(encoded.len(), l);
545 assert_eq!(Compact::compact_len(&n), l);
546 assert_eq!(<Compact<u32>>::decode(&mut &encoded[..]).unwrap().0, n);
547 }
548 }
549
550 #[test]
551 fn compact_16_encoding_works() {
552 let tests = [(0u16, 1usize), (63, 1), (64, 1), (16383, 2), (16384, 3), (65535, 3)];
553 for &(n, l) in &tests {
554 let encoded = Compact(n).encode();
555 assert_eq!(encoded.len(), l);
556 assert_eq!(Compact::compact_len(&n), l);
557 assert_eq!(<Compact<u16>>::decode(&mut &encoded[..]).unwrap().0, n);
558 }
559 assert!(<Compact<u16>>::decode(&mut &Compact(65536u32).encode()[..]).is_err());
560 }
561
562 #[test]
563 fn compact_8_encoding_works() {
564 let tests = [(0u8, 1usize), (63, 1), (64, 1), (255, 2)];
565 for &(n, l) in &tests {
566 let encoded = Compact(n).encode();
567 assert_eq!(encoded.len(), l);
568 assert_eq!(Compact::compact_len(&n), l);
569 assert_eq!(<Compact<u8>>::decode(&mut &encoded[..]).unwrap().0, n);
570 }
571 assert!(<Compact<u8>>::decode(&mut &Compact(256u32).encode()[..]).is_err());
572 }
573
574 fn hexify(bytes: &[u8]) -> String {
575 bytes
576 .iter()
577 .map(|ref b| format!("{:02x}", b))
578 .collect::<Vec<String>>()
579 .join(" ")
580 }
581
582 #[test]
583 fn compact_integers_encoded_as_expected() {
584 let tests = [
585 (0u64, "00"),
586 (63, "3f"),
587 (64, "40"),
588 (16383, "bf ff"),
589 (16384, "c0 00 40"),
590 (1073741823, "f0 ff ff ff 3f"),
591 (1073741824, "f0 00 00 00 40"),
592 ((1 << 32) - 1, "f0 ff ff ff ff"),
593 (1 << 32, "f1 00 00 00 00"),
594 (1 << 40, "f9 00 00 00 00 00"),
595 (1 << 48, "fd 00 00 00 00 00 00"),
596 ((1 << 56) - 1, "fe ff ff ff ff ff ff ff"),
597 (1 << 56, "ff 00 00 00 00 00 00 00 01"),
598 (u64::MAX, "ff ff ff ff ff ff ff ff ff"),
599 ];
600 for &(n, s) in &tests {
601 let encoded = Compact(n).encode();
603 assert_eq!(hexify(&encoded), s);
604 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
605
606 if n <= u32::MAX as u64 {
608 assert_eq!(<Compact<u32>>::decode(&mut &encoded[..]).unwrap().0, n as u32);
609 let encoded = Compact(n as u32).encode();
610 assert_eq!(hexify(&encoded), s);
611 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
612 }
613 if n <= u16::MAX as u64 {
614 assert_eq!(<Compact<u16>>::decode(&mut &encoded[..]).unwrap().0, n as u16);
615 let encoded = Compact(n as u16).encode();
616 assert_eq!(hexify(&encoded), s);
617 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
618 }
619 if n <= u8::MAX as u64 {
620 assert_eq!(<Compact<u8>>::decode(&mut &encoded[..]).unwrap().0, n as u8);
621 let encoded = Compact(n as u8).encode();
622 assert_eq!(hexify(&encoded), s);
623 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
624 }
625 }
626 }
627
628 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
629 #[derive(PartialEq, Eq, Clone)]
630 struct Wrapper(u8);
631
632 impl CompactAs for Wrapper {
633 type As = u8;
634 fn encode_as(&self) -> &u8 {
635 &self.0
636 }
637 fn decode_from(x: u8) -> Result<Wrapper, Error> {
638 Ok(Wrapper(x))
639 }
640 }
641
642 impl From<Compact<Wrapper>> for Wrapper {
643 fn from(x: Compact<Wrapper>) -> Wrapper {
644 x.0
645 }
646 }
647
648 #[test]
649 fn compact_as_8_encoding_works() {
650 let tests = [(0u8, 1usize), (63, 1), (64, 1), (255, 2)];
651 for &(n, l) in &tests {
652 let compact: Compact<Wrapper> = Wrapper(n).into();
653 let encoded = compact.encode();
654 assert_eq!(encoded.len(), l);
655 assert_eq!(Compact::compact_len(&n), l);
656 let decoded = <Compact<Wrapper>>::decode(&mut &encoded[..]).unwrap();
657 let wrapper: Wrapper = decoded.into();
658 assert_eq!(wrapper, Wrapper(n));
659 }
660 }
661
662 struct WithCompact<T: HasCompact> {
663 _data: T,
664 }
665
666 #[test]
667 fn compact_as_has_compact() {
668 let _data = WithCompact { _data: Wrapper(1) };
669 }
670
671 #[test]
672 fn compact_using_encoded_arrayvec_size() {
673 Compact(u8::MAX).using_encoded(|_| {});
674 Compact(u16::MAX).using_encoded(|_| {});
675 Compact(u32::MAX).using_encoded(|_| {});
676 Compact(u64::MAX).using_encoded(|_| {});
677 Compact(u128::MAX).using_encoded(|_| {});
678
679 CompactRef(&u8::MAX).using_encoded(|_| {});
680 CompactRef(&u16::MAX).using_encoded(|_| {});
681 CompactRef(&u32::MAX).using_encoded(|_| {});
682 CompactRef(&u64::MAX).using_encoded(|_| {});
683 CompactRef(&u128::MAX).using_encoded(|_| {});
684 }
685
686 #[test]
687 #[should_panic]
688 fn array_vec_output_oob() {
689 let mut v = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
690 v.write(&[1, 2, 3, 4, 5]);
691 }
692
693 #[test]
694 fn array_vec_output() {
695 let mut v = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
696 v.write(&[1, 2, 3, 4]);
697 }
698
699 #[test]
700 fn compact_u64_test() {
701 for a in [
702 u64::MAX,
703 u64::MAX - 1,
704 u64::MAX << 8,
705 (u64::MAX << 8) - 1,
706 u64::MAX << 16,
707 (u64::MAX << 16) - 1,
708 ]
709 .iter()
710 {
711 let e = Compact::<u64>::encode(&Compact(*a));
712 let d = Compact::<u64>::decode(&mut &e[..]).unwrap().0;
713 assert_eq!(*a, d);
714 }
715 }
716
717 #[test]
718 fn compact_u128_test() {
719 for a in [u64::MAX as u128, (u64::MAX - 10) as u128, u128::MAX, u128::MAX - 10].iter() {
720 let e = Compact::<u128>::encode(&Compact(*a));
721 let d = Compact::<u128>::decode(&mut &e[..]).unwrap().0;
722 assert_eq!(*a, d);
723 }
724 }
725
726 macro_rules! quick_check_roundtrip {
727 ( $( $ty:ty : $test:ident ),* ) => {
728 $(
729 quickcheck::quickcheck! {
730 fn $test(v: $ty) -> bool {
731 let encoded = Compact(v).encode();
732 let deencoded = <Compact<$ty>>::decode(&mut &encoded[..]).unwrap().0;
733
734 v == deencoded
735 }
736 }
737 )*
738 }
739 }
740
741 quick_check_roundtrip! {
742 u8: u8_roundtrip,
743 u16: u16_roundtrip,
744 u32 : u32_roundtrip,
745 u64 : u64_roundtrip,
746 u128 : u128_roundtrip
747 }
748}