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
49struct PrefixInput<'a, T> {
51 prefix: Option<u8>,
52 input: &'a mut T,
53}
54
55impl<'a, T: 'a + Input> Input for PrefixInput<'a, T> {
56 fn remaining_len(&mut self) -> Result<Option<usize>, Error> {
57 let len = if let Some(len) = self.input.remaining_len()? {
58 Some(len.saturating_add(self.prefix.iter().count()))
59 } else {
60 None
61 };
62 Ok(len)
63 }
64
65 fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
66 if buffer.is_empty() {
67 return Ok(());
68 }
69 match self.prefix.take() {
70 Some(v) => {
71 buffer[0] = v;
72 self.input.read(&mut buffer[1..])
73 },
74 _ => self.input.read(buffer),
75 }
76 }
77}
78
79pub trait CompactLen<T> {
81 fn compact_len(val: &T) -> usize;
83}
84
85#[derive(Eq, PartialEq, Clone, Copy, Ord, PartialOrd)]
87#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
88pub struct Compact<T>(pub T);
89
90impl<T> From<T> for Compact<T> {
91 fn from(x: T) -> Compact<T> {
92 Compact(x)
93 }
94}
95
96impl<'a, T: Copy> From<&'a T> for Compact<T> {
97 fn from(x: &'a T) -> Compact<T> {
98 Compact(*x)
99 }
100}
101
102pub trait CompactAs: From<Compact<Self>> {
104 type As;
106
107 fn encode_as(&self) -> &Self::As;
109
110 fn decode_from(_: Self::As) -> Result<Self, Error>;
112}
113
114impl<T> EncodeLike for Compact<T> where for<'a> CompactRef<'a, T>: Encode {}
115
116impl<T> Encode for Compact<T>
117where
118 for<'a> CompactRef<'a, T>: Encode,
119{
120 fn size_hint(&self) -> usize {
121 CompactRef(&self.0).size_hint()
122 }
123
124 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
125 CompactRef(&self.0).encode_to(dest)
126 }
127
128 fn encode(&self) -> Vec<u8> {
129 CompactRef(&self.0).encode()
130 }
131
132 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
133 CompactRef(&self.0).using_encoded(f)
134 }
135}
136
137impl<T> EncodeLike for CompactRef<'_, T>
138where
139 T: CompactAs,
140 for<'b> CompactRef<'b, T::As>: Encode,
141{
142}
143
144impl<T> Encode for CompactRef<'_, T>
145where
146 T: CompactAs,
147 for<'b> CompactRef<'b, T::As>: Encode,
148{
149 fn size_hint(&self) -> usize {
150 CompactRef(self.0.encode_as()).size_hint()
151 }
152
153 fn encode_to<Out: Output + ?Sized>(&self, dest: &mut Out) {
154 CompactRef(self.0.encode_as()).encode_to(dest)
155 }
156
157 fn encode(&self) -> Vec<u8> {
158 CompactRef(self.0.encode_as()).encode()
159 }
160
161 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
162 CompactRef(self.0.encode_as()).using_encoded(f)
163 }
164}
165
166impl<T> Decode for Compact<T>
167where
168 T: CompactAs,
169 Compact<T::As>: Decode,
170{
171 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
172 let as_ = Compact::<T::As>::decode(input)?;
173 Ok(Compact(<T as CompactAs>::decode_from(as_.0)?))
174 }
175}
176
177impl<T> DecodeWithMemTracking for Compact<T>
178where
179 T: CompactAs,
180 Compact<T::As>: DecodeWithMemTracking,
181{
182}
183
184macro_rules! impl_from_compact {
185 ( $( $ty:ty ),* ) => {
186 $(
187 impl From<Compact<$ty>> for $ty {
188 fn from(x: Compact<$ty>) -> $ty { x.0 }
189 }
190 )*
191 }
192}
193
194impl_from_compact! { (), u8, u16, u32, u64, u128 }
195
196#[derive(Eq, PartialEq, Clone, Copy)]
198pub struct CompactRef<'a, T>(pub &'a T);
199
200impl<'a, T> From<&'a T> for CompactRef<'a, T> {
201 fn from(x: &'a T) -> Self {
202 CompactRef(x)
203 }
204}
205
206impl<T> core::fmt::Debug for Compact<T>
207where
208 T: core::fmt::Debug,
209{
210 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
211 self.0.fmt(f)
212 }
213}
214
215#[cfg(feature = "serde")]
216impl<T> serde::Serialize for Compact<T>
217where
218 T: serde::Serialize,
219{
220 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
221 where
222 S: serde::Serializer,
223 {
224 T::serialize(&self.0, serializer)
225 }
226}
227
228#[cfg(feature = "serde")]
229impl<'de, T> serde::Deserialize<'de> for Compact<T>
230where
231 T: serde::Deserialize<'de>,
232{
233 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
234 where
235 D: serde::Deserializer<'de>,
236 {
237 T::deserialize(deserializer).map(Compact)
238 }
239}
240
241pub trait HasCompact: Sized {
243 type Type: for<'a> EncodeAsRef<'a, Self> + Decode + From<Self> + Into<Self>;
245}
246
247impl<'a, T: 'a> EncodeAsRef<'a, T> for Compact<T>
248where
249 CompactRef<'a, T>: Encode + From<&'a T>,
250{
251 type RefType = CompactRef<'a, T>;
252}
253
254impl<T: 'static> HasCompact for T
255where
256 Compact<T>: for<'a> EncodeAsRef<'a, T> + Decode + From<Self> + Into<Self>,
257{
258 type Type = Compact<T>;
259}
260
261impl Encode for CompactRef<'_, ()> {
262 fn encode_to<W: Output + ?Sized>(&self, _dest: &mut W) {}
263
264 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
265 f(&[])
266 }
267
268 fn encode(&self) -> Vec<u8> {
269 Vec::new()
270 }
271}
272
273impl Encode for CompactRef<'_, u8> {
274 fn size_hint(&self) -> usize {
275 Compact::compact_len(self.0)
276 }
277
278 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
279 match self.0 {
280 0..=0b0011_1111 => dest.push_byte(self.0 << 2),
281 _ => ((u16::from(*self.0) << 2) | 0b01).encode_to(dest),
282 }
283 }
284
285 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
286 let mut r = ArrayVecWrapper(ArrayVec::<u8, 2>::new());
287 self.encode_to(&mut r);
288 f(&r.0)
289 }
290}
291
292impl CompactLen<u8> for Compact<u8> {
293 fn compact_len(val: &u8) -> usize {
294 match val {
295 0..=0b0011_1111 => 1,
296 _ => 2,
297 }
298 }
299}
300
301impl Encode for CompactRef<'_, u16> {
302 fn size_hint(&self) -> usize {
303 Compact::compact_len(self.0)
304 }
305
306 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
307 match self.0 {
308 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
309 0..=0b0011_1111_1111_1111 => ((*self.0 << 2) | 0b01).encode_to(dest),
310 _ => ((u32::from(*self.0) << 2) | 0b10).encode_to(dest),
311 }
312 }
313
314 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
315 let mut r = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
316 self.encode_to(&mut r);
317 f(&r.0)
318 }
319}
320
321impl CompactLen<u16> for Compact<u16> {
322 fn compact_len(val: &u16) -> usize {
323 match val {
324 0..=0b0011_1111 => 1,
325 0..=0b0011_1111_1111_1111 => 2,
326 _ => 4,
327 }
328 }
329}
330
331impl Encode for CompactRef<'_, u32> {
332 fn size_hint(&self) -> usize {
333 Compact::compact_len(self.0)
334 }
335
336 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
337 match self.0 {
338 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
339 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest),
340 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 =>
341 ((*self.0 << 2) | 0b10).encode_to(dest),
342 _ => {
343 dest.push_byte(0b11);
344 self.0.encode_to(dest);
345 },
346 }
347 }
348
349 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
350 let mut r = ArrayVecWrapper(ArrayVec::<u8, 5>::new());
351 self.encode_to(&mut r);
352 f(&r.0)
353 }
354}
355
356impl CompactLen<u32> for Compact<u32> {
357 fn compact_len(val: &u32) -> usize {
358 match val {
359 0..=0b0011_1111 => 1,
360 0..=0b0011_1111_1111_1111 => 2,
361 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => 4,
362 _ => 5,
363 }
364 }
365}
366
367impl Encode for CompactRef<'_, u64> {
368 fn size_hint(&self) -> usize {
369 Compact::compact_len(self.0)
370 }
371
372 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
373 match self.0 {
374 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
375 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest),
376 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 =>
377 (((*self.0 as u32) << 2) | 0b10).encode_to(dest),
378 _ => {
379 let bytes_needed = 8 - self.0.leading_zeros() / 8;
380 assert!(
381 bytes_needed >= 4,
382 "Previous match arm matches anyting less than 2^30; qed"
383 );
384 dest.push_byte(0b11 + ((bytes_needed - 4) << 2) as u8);
385 let mut v = *self.0;
386 for _ in 0..bytes_needed {
387 dest.push_byte(v as u8);
388 v >>= 8;
389 }
390 assert_eq!(v, 0, "shifted sufficient bits right to lead only leading zeros; qed")
391 },
392 }
393 }
394
395 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
396 let mut r = ArrayVecWrapper(ArrayVec::<u8, 9>::new());
397 self.encode_to(&mut r);
398 f(&r.0)
399 }
400}
401
402impl CompactLen<u64> for Compact<u64> {
403 fn compact_len(val: &u64) -> usize {
404 match val {
405 0..=0b0011_1111 => 1,
406 0..=0b0011_1111_1111_1111 => 2,
407 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => 4,
408 _ => (8 - val.leading_zeros() / 8) as usize + 1,
409 }
410 }
411}
412
413impl Encode for CompactRef<'_, u128> {
414 fn size_hint(&self) -> usize {
415 Compact::compact_len(self.0)
416 }
417
418 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
419 match self.0 {
420 0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
421 0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest),
422 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 =>
423 (((*self.0 as u32) << 2) | 0b10).encode_to(dest),
424 _ => {
425 let bytes_needed = 16 - self.0.leading_zeros() / 8;
426 assert!(
427 bytes_needed >= 4,
428 "Previous match arm matches anyting less than 2^30; qed"
429 );
430 dest.push_byte(0b11 + ((bytes_needed - 4) << 2) as u8);
431 let mut v = *self.0;
432 for _ in 0..bytes_needed {
433 dest.push_byte(v as u8);
434 v >>= 8;
435 }
436 assert_eq!(v, 0, "shifted sufficient bits right to lead only leading zeros; qed")
437 },
438 }
439 }
440
441 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
442 let mut r = ArrayVecWrapper(ArrayVec::<u8, 17>::new());
443 self.encode_to(&mut r);
444 f(&r.0)
445 }
446}
447
448impl CompactLen<u128> for Compact<u128> {
449 fn compact_len(val: &u128) -> usize {
450 match val {
451 0..=0b0011_1111 => 1,
452 0..=0b0011_1111_1111_1111 => 2,
453 0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => 4,
454 _ => (16 - val.leading_zeros() / 8) as usize + 1,
455 }
456 }
457}
458
459impl Decode for Compact<()> {
460 fn decode<I: Input>(_input: &mut I) -> Result<Self, Error> {
461 Ok(Compact(()))
462 }
463}
464
465impl DecodeWithMemTracking for Compact<()> {}
466
467const U8_OUT_OF_RANGE: &str = "out of range decoding Compact<u8>";
468const U16_OUT_OF_RANGE: &str = "out of range decoding Compact<u16>";
469const U32_OUT_OF_RANGE: &str = "out of range decoding Compact<u32>";
470const U64_OUT_OF_RANGE: &str = "out of range decoding Compact<u64>";
471const U128_OUT_OF_RANGE: &str = "out of range decoding Compact<u128>";
472
473impl Decode for Compact<u8> {
474 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
475 let prefix = input.read_byte()?;
476 Ok(Compact(match prefix % 4 {
477 0 => prefix >> 2,
478 1 => {
479 let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
480 if x > 0b0011_1111 && x <= 255 {
481 x as u8
482 } else {
483 return Err(U8_OUT_OF_RANGE.into());
484 }
485 },
486 _ => return Err("unexpected prefix decoding Compact<u8>".into()),
487 }))
488 }
489}
490
491impl DecodeWithMemTracking for Compact<u8> {}
492
493impl Decode for Compact<u16> {
494 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
495 let prefix = input.read_byte()?;
496 Ok(Compact(match prefix % 4 {
497 0 => u16::from(prefix) >> 2,
498 1 => {
499 let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
500 if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 {
501 x
502 } else {
503 return Err(U16_OUT_OF_RANGE.into());
504 }
505 },
506 2 => {
507 let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
508 if x > 0b0011_1111_1111_1111 && x < 65536 {
509 x as u16
510 } else {
511 return Err(U16_OUT_OF_RANGE.into());
512 }
513 },
514 _ => return Err("unexpected prefix decoding Compact<u16>".into()),
515 }))
516 }
517}
518
519impl DecodeWithMemTracking for Compact<u16> {}
520
521impl Decode for Compact<u32> {
522 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
523 let prefix = input.read_byte()?;
524 Ok(Compact(match prefix % 4 {
525 0 => u32::from(prefix) >> 2,
526 1 => {
527 let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
528 if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 {
529 u32::from(x)
530 } else {
531 return Err(U32_OUT_OF_RANGE.into());
532 }
533 },
534 2 => {
535 let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
536 if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 {
537 x
538 } else {
539 return Err(U32_OUT_OF_RANGE.into());
540 }
541 },
542 3 => {
543 if prefix >> 2 == 0 {
544 let x = u32::decode(input)?;
546 if x > u32::MAX >> 2 {
547 x
548 } else {
549 return Err(U32_OUT_OF_RANGE.into());
550 }
551 } else {
552 return Err(U32_OUT_OF_RANGE.into());
554 }
555 },
556 _ => unreachable!(),
557 }))
558 }
559}
560
561impl DecodeWithMemTracking for Compact<u32> {}
562
563impl Decode for Compact<u64> {
564 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
565 let prefix = input.read_byte()?;
566 Ok(Compact(match prefix % 4 {
567 0 => u64::from(prefix) >> 2,
568 1 => {
569 let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
570 if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 {
571 u64::from(x)
572 } else {
573 return Err(U64_OUT_OF_RANGE.into());
574 }
575 },
576 2 => {
577 let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
578 if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 {
579 u64::from(x)
580 } else {
581 return Err(U64_OUT_OF_RANGE.into());
582 }
583 },
584 3 => match (prefix >> 2) + 4 {
585 4 => {
586 let x = u32::decode(input)?;
587 if x > u32::MAX >> 2 {
588 u64::from(x)
589 } else {
590 return Err(U64_OUT_OF_RANGE.into());
591 }
592 },
593 8 => {
594 let x = u64::decode(input)?;
595 if x > u64::MAX >> 8 {
596 x
597 } else {
598 return Err(U64_OUT_OF_RANGE.into());
599 }
600 },
601 x if x > 8 => return Err("unexpected prefix decoding Compact<u64>".into()),
602 bytes_needed => {
603 let mut res = 0;
604 for i in 0..bytes_needed {
605 res |= u64::from(input.read_byte()?) << (i * 8);
606 }
607 if res > u64::MAX >> ((8 - bytes_needed + 1) * 8) {
608 res
609 } else {
610 return Err(U64_OUT_OF_RANGE.into());
611 }
612 },
613 },
614 _ => unreachable!(),
615 }))
616 }
617}
618
619impl DecodeWithMemTracking for Compact<u64> {}
620
621impl Decode for Compact<u128> {
622 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
623 let prefix = input.read_byte()?;
624 Ok(Compact(match prefix % 4 {
625 0 => u128::from(prefix) >> 2,
626 1 => {
627 let x = u16::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
628 if x > 0b0011_1111 && x <= 0b0011_1111_1111_1111 {
629 u128::from(x)
630 } else {
631 return Err(U128_OUT_OF_RANGE.into());
632 }
633 },
634 2 => {
635 let x = u32::decode(&mut PrefixInput { prefix: Some(prefix), input })? >> 2;
636 if x > 0b0011_1111_1111_1111 && x <= u32::MAX >> 2 {
637 u128::from(x)
638 } else {
639 return Err(U128_OUT_OF_RANGE.into());
640 }
641 },
642 3 => match (prefix >> 2) + 4 {
643 4 => {
644 let x = u32::decode(input)?;
645 if x > u32::MAX >> 2 {
646 u128::from(x)
647 } else {
648 return Err(U128_OUT_OF_RANGE.into());
649 }
650 },
651 8 => {
652 let x = u64::decode(input)?;
653 if x > u64::MAX >> 8 {
654 u128::from(x)
655 } else {
656 return Err(U128_OUT_OF_RANGE.into());
657 }
658 },
659 16 => {
660 let x = u128::decode(input)?;
661 if x > u128::MAX >> 8 {
662 x
663 } else {
664 return Err(U128_OUT_OF_RANGE.into());
665 }
666 },
667 x if x > 16 => return Err("unexpected prefix decoding Compact<u128>".into()),
668 bytes_needed => {
669 let mut res = 0;
670 for i in 0..bytes_needed {
671 res |= u128::from(input.read_byte()?) << (i * 8);
672 }
673 if res > u128::MAX >> ((16 - bytes_needed + 1) * 8) {
674 res
675 } else {
676 return Err(U128_OUT_OF_RANGE.into());
677 }
678 },
679 },
680 _ => unreachable!(),
681 }))
682 }
683}
684
685impl DecodeWithMemTracking for Compact<u128> {}
686
687#[cfg(test)]
688mod tests {
689 use super::*;
690
691 #[test]
692 fn prefix_input_empty_read_unchanged() {
693 let mut input = PrefixInput { prefix: Some(1), input: &mut &vec![2, 3, 4][..] };
694 assert_eq!(input.remaining_len(), Ok(Some(4)));
695 let mut empty_buf = [];
696 assert_eq!(input.read(&mut empty_buf[..]), Ok(()));
697 assert_eq!(input.remaining_len(), Ok(Some(4)));
698 assert_eq!(input.read_byte(), Ok(1));
699 }
700
701 #[test]
702 fn compact_128_encoding_works() {
703 let tests = [
704 (0u128, 1usize),
705 (63, 1),
706 (64, 2),
707 (16383, 2),
708 (16384, 4),
709 (1073741823, 4),
710 (1073741824, 5),
711 ((1 << 32) - 1, 5),
712 (1 << 32, 6),
713 (1 << 40, 7),
714 (1 << 48, 8),
715 ((1 << 56) - 1, 8),
716 (1 << 56, 9),
717 ((1 << 64) - 1, 9),
718 (1 << 64, 10),
719 (1 << 72, 11),
720 (1 << 80, 12),
721 (1 << 88, 13),
722 (1 << 96, 14),
723 (1 << 104, 15),
724 (1 << 112, 16),
725 ((1 << 120) - 1, 16),
726 (1 << 120, 17),
727 (u128::MAX, 17),
728 ];
729 for &(n, l) in &tests {
730 let encoded = Compact(n).encode();
731 assert_eq!(encoded.len(), l);
732 assert_eq!(Compact::compact_len(&n), l);
733 assert_eq!(<Compact<u128>>::decode(&mut &encoded[..]).unwrap().0, n);
734 }
735 }
736
737 #[test]
738 fn compact_64_encoding_works() {
739 let tests = [
740 (0u64, 1usize),
741 (63, 1),
742 (64, 2),
743 (16383, 2),
744 (16384, 4),
745 (1073741823, 4),
746 (1073741824, 5),
747 ((1 << 32) - 1, 5),
748 (1 << 32, 6),
749 (1 << 40, 7),
750 (1 << 48, 8),
751 ((1 << 56) - 1, 8),
752 (1 << 56, 9),
753 (u64::MAX, 9),
754 ];
755 for &(n, l) in &tests {
756 let encoded = Compact(n).encode();
757 assert_eq!(encoded.len(), l);
758 assert_eq!(Compact::compact_len(&n), l);
759 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
760 }
761 }
762
763 #[test]
764 fn compact_32_encoding_works() {
765 let tests = [
766 (0u32, 1usize),
767 (63, 1),
768 (64, 2),
769 (16383, 2),
770 (16384, 4),
771 (1073741823, 4),
772 (1073741824, 5),
773 (u32::MAX, 5),
774 ];
775 for &(n, l) in &tests {
776 let encoded = Compact(n).encode();
777 assert_eq!(encoded.len(), l);
778 assert_eq!(Compact::compact_len(&n), l);
779 assert_eq!(<Compact<u32>>::decode(&mut &encoded[..]).unwrap().0, n);
780 }
781 }
782
783 #[test]
784 fn compact_16_encoding_works() {
785 let tests = [(0u16, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (65535, 4)];
786 for &(n, l) in &tests {
787 let encoded = Compact(n).encode();
788 assert_eq!(encoded.len(), l);
789 assert_eq!(Compact::compact_len(&n), l);
790 assert_eq!(<Compact<u16>>::decode(&mut &encoded[..]).unwrap().0, n);
791 }
792 assert!(<Compact<u16>>::decode(&mut &Compact(65536u32).encode()[..]).is_err());
793 }
794
795 #[test]
796 fn compact_8_encoding_works() {
797 let tests = [(0u8, 1usize), (63, 1), (64, 2), (255, 2)];
798 for &(n, l) in &tests {
799 let encoded = Compact(n).encode();
800 assert_eq!(encoded.len(), l);
801 assert_eq!(Compact::compact_len(&n), l);
802 assert_eq!(<Compact<u8>>::decode(&mut &encoded[..]).unwrap().0, n);
803 }
804 assert!(<Compact<u8>>::decode(&mut &Compact(256u32).encode()[..]).is_err());
805 }
806
807 fn hexify(bytes: &[u8]) -> String {
808 bytes
809 .iter()
810 .map(|ref b| format!("{:02x}", b))
811 .collect::<Vec<String>>()
812 .join(" ")
813 }
814
815 #[test]
816 fn compact_integers_encoded_as_expected() {
817 let tests = [
818 (0u64, "00"),
819 (63, "fc"),
820 (64, "01 01"),
821 (16383, "fd ff"),
822 (16384, "02 00 01 00"),
823 (1073741823, "fe ff ff ff"),
824 (1073741824, "03 00 00 00 40"),
825 ((1 << 32) - 1, "03 ff ff ff ff"),
826 (1 << 32, "07 00 00 00 00 01"),
827 (1 << 40, "0b 00 00 00 00 00 01"),
828 (1 << 48, "0f 00 00 00 00 00 00 01"),
829 ((1 << 56) - 1, "0f ff ff ff ff ff ff ff"),
830 (1 << 56, "13 00 00 00 00 00 00 00 01"),
831 (u64::MAX, "13 ff ff ff ff ff ff ff ff"),
832 ];
833 for &(n, s) in &tests {
834 let encoded = Compact(n).encode();
836 assert_eq!(hexify(&encoded), s);
837 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
838
839 if n <= u32::MAX as u64 {
841 assert_eq!(<Compact<u32>>::decode(&mut &encoded[..]).unwrap().0, n as u32);
842 let encoded = Compact(n as u32).encode();
843 assert_eq!(hexify(&encoded), s);
844 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
845 }
846 if n <= u16::MAX as u64 {
847 assert_eq!(<Compact<u16>>::decode(&mut &encoded[..]).unwrap().0, n as u16);
848 let encoded = Compact(n as u16).encode();
849 assert_eq!(hexify(&encoded), s);
850 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
851 }
852 if n <= u8::MAX as u64 {
853 assert_eq!(<Compact<u8>>::decode(&mut &encoded[..]).unwrap().0, n as u8);
854 let encoded = Compact(n as u8).encode();
855 assert_eq!(hexify(&encoded), s);
856 assert_eq!(<Compact<u64>>::decode(&mut &encoded[..]).unwrap().0, n);
857 }
858 }
859 }
860
861 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
862 #[derive(PartialEq, Eq, Clone)]
863 struct Wrapper(u8);
864
865 impl CompactAs for Wrapper {
866 type As = u8;
867 fn encode_as(&self) -> &u8 {
868 &self.0
869 }
870 fn decode_from(x: u8) -> Result<Wrapper, Error> {
871 Ok(Wrapper(x))
872 }
873 }
874
875 impl From<Compact<Wrapper>> for Wrapper {
876 fn from(x: Compact<Wrapper>) -> Wrapper {
877 x.0
878 }
879 }
880
881 #[test]
882 fn compact_as_8_encoding_works() {
883 let tests = [(0u8, 1usize), (63, 1), (64, 2), (255, 2)];
884 for &(n, l) in &tests {
885 let compact: Compact<Wrapper> = Wrapper(n).into();
886 let encoded = compact.encode();
887 assert_eq!(encoded.len(), l);
888 assert_eq!(Compact::compact_len(&n), l);
889 let decoded = <Compact<Wrapper>>::decode(&mut &encoded[..]).unwrap();
890 let wrapper: Wrapper = decoded.into();
891 assert_eq!(wrapper, Wrapper(n));
892 }
893 }
894
895 struct WithCompact<T: HasCompact> {
896 _data: T,
897 }
898
899 #[test]
900 fn compact_as_has_compact() {
901 let _data = WithCompact { _data: Wrapper(1) };
902 }
903
904 #[test]
905 fn compact_using_encoded_arrayvec_size() {
906 Compact(u8::MAX).using_encoded(|_| {});
907 Compact(u16::MAX).using_encoded(|_| {});
908 Compact(u32::MAX).using_encoded(|_| {});
909 Compact(u64::MAX).using_encoded(|_| {});
910 Compact(u128::MAX).using_encoded(|_| {});
911
912 CompactRef(&u8::MAX).using_encoded(|_| {});
913 CompactRef(&u16::MAX).using_encoded(|_| {});
914 CompactRef(&u32::MAX).using_encoded(|_| {});
915 CompactRef(&u64::MAX).using_encoded(|_| {});
916 CompactRef(&u128::MAX).using_encoded(|_| {});
917 }
918
919 #[test]
920 #[should_panic]
921 fn array_vec_output_oob() {
922 let mut v = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
923 v.write(&[1, 2, 3, 4, 5]);
924 }
925
926 #[test]
927 fn array_vec_output() {
928 let mut v = ArrayVecWrapper(ArrayVec::<u8, 4>::new());
929 v.write(&[1, 2, 3, 4]);
930 }
931
932 macro_rules! check_bound {
933 ( $m:expr, $ty:ty, $typ1:ty, [ $(($ty2:ty, $ty2_err:expr)),* ]) => {
934 $(
935 check_bound!($m, $ty, $typ1, $ty2, $ty2_err);
936 )*
937 };
938 ( $m:expr, $ty:ty, $typ1:ty, $ty2:ty, $ty2_err:expr) => {
939 let enc = ((<$ty>::MAX >> 2) as $typ1 << 2) | $m;
940 assert_eq!(Compact::<$ty2>::decode(&mut &enc.to_le_bytes()[..]),
941 Err($ty2_err.into()));
942 };
943 }
944 macro_rules! check_bound_u32 {
945 ( [ $(($ty2:ty, $ty2_err:expr)),* ]) => {
946 $(
947 check_bound_u32!($ty2, $ty2_err);
948 )*
949 };
950 ( $ty2:ty, $ty2_err:expr ) => {
951 assert_eq!(Compact::<$ty2>::decode(&mut &[0b11, 0xff, 0xff, 0xff, 0xff >> 2][..]),
952 Err($ty2_err.into()));
953 };
954 }
955 macro_rules! check_bound_high {
956 ( $m:expr, [ $(($ty2:ty, $ty2_err:expr)),* ]) => {
957 $(
958 check_bound_high!($m, $ty2, $ty2_err);
959 )*
960 };
961 ( $s:expr, $ty2:ty, $ty2_err:expr) => {
962 let mut dest = Vec::new();
963 dest.push(0b11 + (($s - 4) << 2) as u8);
964 for _ in 0..($s - 1) {
965 dest.push(u8::MAX);
966 }
967 dest.push(0);
968 assert_eq!(Compact::<$ty2>::decode(&mut &dest[..]),
969 Err($ty2_err.into()));
970 };
971 }
972
973 #[test]
974 fn compact_u64_test() {
975 for a in [
976 u64::MAX,
977 u64::MAX - 1,
978 u64::MAX << 8,
979 (u64::MAX << 8) - 1,
980 u64::MAX << 16,
981 (u64::MAX << 16) - 1,
982 ]
983 .iter()
984 {
985 let e = Compact::<u64>::encode(&Compact(*a));
986 let d = Compact::<u64>::decode(&mut &e[..]).unwrap().0;
987 assert_eq!(*a, d);
988 }
989 }
990
991 #[test]
992 fn compact_u128_test() {
993 for a in [u64::MAX as u128, (u64::MAX - 10) as u128, u128::MAX, u128::MAX - 10].iter() {
994 let e = Compact::<u128>::encode(&Compact(*a));
995 let d = Compact::<u128>::decode(&mut &e[..]).unwrap().0;
996 assert_eq!(*a, d);
997 }
998 }
999
1000 #[test]
1001 fn should_avoid_overlapping_definition() {
1002 check_bound!(
1003 0b01,
1004 u8,
1005 u16,
1006 [
1007 (u8, U8_OUT_OF_RANGE),
1008 (u16, U16_OUT_OF_RANGE),
1009 (u32, U32_OUT_OF_RANGE),
1010 (u64, U64_OUT_OF_RANGE),
1011 (u128, U128_OUT_OF_RANGE)
1012 ]
1013 );
1014 check_bound!(
1015 0b10,
1016 u16,
1017 u32,
1018 [
1019 (u16, U16_OUT_OF_RANGE),
1020 (u32, U32_OUT_OF_RANGE),
1021 (u64, U64_OUT_OF_RANGE),
1022 (u128, U128_OUT_OF_RANGE)
1023 ]
1024 );
1025 check_bound_u32!([
1026 (u32, U32_OUT_OF_RANGE),
1027 (u64, U64_OUT_OF_RANGE),
1028 (u128, U128_OUT_OF_RANGE)
1029 ]);
1030 for i in 5..=8 {
1031 check_bound_high!(i, [(u64, U64_OUT_OF_RANGE), (u128, U128_OUT_OF_RANGE)]);
1032 }
1033 for i in 8..=16 {
1034 check_bound_high!(i, [(u128, U128_OUT_OF_RANGE)]);
1035 }
1036 }
1037
1038 macro_rules! quick_check_roundtrip {
1039 ( $( $ty:ty : $test:ident ),* ) => {
1040 $(
1041 quickcheck::quickcheck! {
1042 fn $test(v: $ty) -> bool {
1043 let encoded = Compact(v).encode();
1044 let deencoded = <Compact<$ty>>::decode(&mut &encoded[..]).unwrap().0;
1045
1046 v == deencoded
1047 }
1048 }
1049 )*
1050 }
1051 }
1052
1053 quick_check_roundtrip! {
1054 u8: u8_roundtrip,
1055 u16: u16_roundtrip,
1056 u32 : u32_roundtrip,
1057 u64 : u64_roundtrip,
1058 u128 : u128_roundtrip
1059 }
1060}