tetsy_scale_codec/
decode_all.rs1use crate::{Error, Decode};
16
17pub(crate) const DECODE_ALL_ERR_MSG: &str = "Input buffer has still data left after decoding!";
19
20pub trait DecodeAll: Sized {
23 fn decode_all(input: &[u8]) -> Result<Self, Error>;
27}
28
29impl<T: Decode> DecodeAll for T {
30 fn decode_all(input: &[u8]) -> Result<Self, Error> {
31 let input = &mut &input[..];
32 let res = T::decode(input)?;
33
34 if input.is_empty() {
35 Ok(res)
36 } else {
37 Err(DECODE_ALL_ERR_MSG.into())
38 }
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::{Encode, Input, Compact, EncodeLike};
46
47 macro_rules! test_decode_all {
48 (
49 $( $type:ty => $value:expr; )*
50 ) => {
51 $(
52 {
53 let mut encoded = <$type as Encode>::encode(&$value);
54 <$type>::decode_all(&encoded).expect(
55 &format!("`{} => {}` decodes all!", stringify!($type), stringify!($value)),
56 );
57
58 encoded.extend(&[1, 2, 3, 4, 5, 6]);
59 assert_eq!(
60 <$type>::decode_all(&encoded).unwrap_err().to_string(),
61 "Input buffer has still data left after decoding!",
62 );
63 }
64 )*
65 };
66 }
67
68 #[derive(Debug)]
69 struct TestStruct {
70 data: Vec<u32>,
71 other: u8,
72 compact: Compact<u128>,
73 }
74
75 impl EncodeLike for TestStruct {}
76
77 impl Encode for TestStruct {
78 fn encode(&self) -> Vec<u8> {
79 let mut res = Vec::new();
80 self.data.encode_to(&mut res);
81 self.other.encode_to(&mut res);
82 self.compact.encode_to(&mut res);
83 res
84 }
85 }
86
87 impl Decode for TestStruct {
88 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
89 Ok(
90 Self {
91 data: Vec::<u32>::decode(input)?,
92 other: u8::decode(input)?,
93 compact: Compact::<u128>::decode(input)?,
94 }
95 )
96 }
97 }
98
99 #[test]
100 fn decode_all_works() {
101 test_decode_all! {
102 u8 => 120;
103 u16 => 30;
104 u32 => 1;
105 u64 => 2343545;
106 u128 => 34358394245459854;
107 Vec<u8> => vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
108 Vec<u32> => vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
109 Compact<u32> => Compact(32445);
110 Compact<u128> => Compact(34353454453545);
111 TestStruct => TestStruct { data: vec![1, 2, 4, 5, 6], other: 45, compact: Compact(123234545) };
112 }
113 }
114}