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