1use crate::{Error, Header, Result};
2use bytes::{Bytes, BytesMut};
3use core::marker::{PhantomData, PhantomPinned};
4
5pub trait Decodable: Sized {
7 fn decode(buf: &mut &[u8]) -> Result<Self>;
10}
11
12#[derive(Debug)]
14pub struct Rlp<'a> {
15 payload_view: &'a [u8],
16}
17
18impl<'a> Rlp<'a> {
19 pub fn new(mut payload: &'a [u8]) -> Result<Self> {
21 let payload_view = Header::decode_bytes(&mut payload, true)?;
22 Ok(Self { payload_view })
23 }
24
25 #[inline]
27 pub fn get_next<T: Decodable>(&mut self) -> Result<Option<T>> {
28 if self.payload_view.is_empty() {
29 Ok(None)
30 } else {
31 T::decode(&mut self.payload_view).map(Some)
32 }
33 }
34}
35
36impl<T: ?Sized> Decodable for PhantomData<T> {
37 fn decode(_buf: &mut &[u8]) -> Result<Self> {
38 Ok(Self)
39 }
40}
41
42impl Decodable for PhantomPinned {
43 fn decode(_buf: &mut &[u8]) -> Result<Self> {
44 Ok(Self)
45 }
46}
47
48impl Decodable for bool {
49 #[inline]
50 fn decode(buf: &mut &[u8]) -> Result<Self> {
51 Ok(match u8::decode(buf)? {
52 0 => false,
53 1 => true,
54 _ => return Err(Error::Custom("invalid bool value, must be 0 or 1")),
55 })
56 }
57}
58
59impl<const N: usize> Decodable for [u8; N] {
60 #[inline]
61 fn decode(from: &mut &[u8]) -> Result<Self> {
62 let bytes = Header::decode_bytes(from, false)?;
63 Self::try_from(bytes).map_err(|_| Error::UnexpectedLength)
64 }
65}
66
67macro_rules! decode_integer {
68 ($($t:ty),+ $(,)?) => {$(
69 impl Decodable for $t {
70 #[inline]
71 fn decode(buf: &mut &[u8]) -> Result<Self> {
72 let bytes = Header::decode_bytes(buf, false)?;
73 static_left_pad(bytes).map(<$t>::from_be_bytes)
74 }
75 }
76 )+};
77}
78
79decode_integer!(u8, u16, u32, u64, usize, u128);
80
81impl Decodable for Bytes {
82 #[inline]
83 fn decode(buf: &mut &[u8]) -> Result<Self> {
84 Header::decode_bytes(buf, false).map(|x| Self::from(x.to_vec()))
85 }
86}
87
88impl Decodable for BytesMut {
89 #[inline]
90 fn decode(buf: &mut &[u8]) -> Result<Self> {
91 Header::decode_bytes(buf, false).map(Self::from)
92 }
93}
94
95impl Decodable for alloc::string::String {
96 #[inline]
97 fn decode(buf: &mut &[u8]) -> Result<Self> {
98 Header::decode_str(buf).map(Into::into)
99 }
100}
101
102impl<T: Decodable> Decodable for alloc::vec::Vec<T> {
103 #[inline]
104 fn decode(buf: &mut &[u8]) -> Result<Self> {
105 let mut bytes = Header::decode_bytes(buf, true)?;
106 let mut vec = Self::new();
107 let payload_view = &mut bytes;
108 while !payload_view.is_empty() {
109 vec.push(T::decode(payload_view)?);
110 }
111 Ok(vec)
112 }
113}
114
115macro_rules! wrap_impl {
116 ($($(#[$attr:meta])* [$($gen:tt)*] <$t:ty>::$new:ident($t2:ty)),+ $(,)?) => {$(
117 $(#[$attr])*
118 impl<$($gen)*> Decodable for $t {
119 #[inline]
120 fn decode(buf: &mut &[u8]) -> Result<Self> {
121 <$t2 as Decodable>::decode(buf).map(<$t>::$new)
122 }
123 }
124 )+};
125}
126
127wrap_impl! {
128 #[cfg(feature = "arrayvec")]
129 [const N: usize] <arrayvec::ArrayVec<u8, N>>::from([u8; N]),
130 [T: Decodable] <alloc::boxed::Box<T>>::new(T),
131 [T: Decodable] <alloc::rc::Rc<T>>::new(T),
132 [T: Decodable] <alloc::sync::Arc<T>>::new(T),
133}
134
135impl<T: ?Sized + alloc::borrow::ToOwned> Decodable for alloc::borrow::Cow<'_, T>
136where
137 T::Owned: Decodable,
138{
139 #[inline]
140 fn decode(buf: &mut &[u8]) -> Result<Self> {
141 T::Owned::decode(buf).map(Self::Owned)
142 }
143}
144
145#[cfg(any(feature = "std", feature = "core-net"))]
146mod std_impl {
147 use super::*;
148 #[cfg(all(feature = "core-net", not(feature = "std")))]
149 use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
150 #[cfg(feature = "std")]
151 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
152
153 impl Decodable for IpAddr {
154 fn decode(buf: &mut &[u8]) -> Result<Self> {
155 let bytes = Header::decode_bytes(buf, false)?;
156 match bytes.len() {
157 4 => Ok(Self::V4(Ipv4Addr::from(slice_to_array::<4>(bytes).expect("infallible")))),
158 16 => {
159 Ok(Self::V6(Ipv6Addr::from(slice_to_array::<16>(bytes).expect("infallible"))))
160 }
161 _ => Err(Error::UnexpectedLength),
162 }
163 }
164 }
165
166 impl Decodable for Ipv4Addr {
167 #[inline]
168 fn decode(buf: &mut &[u8]) -> Result<Self> {
169 let bytes = Header::decode_bytes(buf, false)?;
170 slice_to_array::<4>(bytes).map(Self::from)
171 }
172 }
173
174 impl Decodable for Ipv6Addr {
175 #[inline]
176 fn decode(buf: &mut &[u8]) -> Result<Self> {
177 let bytes = Header::decode_bytes(buf, false)?;
178 slice_to_array::<16>(bytes).map(Self::from)
179 }
180 }
181
182 #[inline]
183 fn slice_to_array<const N: usize>(slice: &[u8]) -> Result<[u8; N]> {
184 slice.try_into().map_err(|_| Error::UnexpectedLength)
185 }
186}
187
188#[inline]
194pub fn decode_exact<T: Decodable>(bytes: impl AsRef<[u8]>) -> Result<T> {
195 let mut buf = bytes.as_ref();
196 let out = T::decode(&mut buf)?;
197
198 if !buf.is_empty() {
200 return Err(Error::UnexpectedLength);
202 }
203
204 Ok(out)
205}
206
207#[inline]
213pub(crate) fn static_left_pad<const N: usize>(data: &[u8]) -> Result<[u8; N]> {
214 if data.len() > N {
215 return Err(Error::Overflow);
216 }
217
218 let mut v = [0; N];
219
220 if data.is_empty() {
222 return Ok(v);
223 }
224
225 if data[0] == 0 {
226 return Err(Error::LeadingZero);
227 }
228
229 unsafe { v.get_unchecked_mut(N - data.len()..) }.copy_from_slice(data);
231 Ok(v)
232}
233
234#[cfg(test)]
235mod tests {
236 use super::*;
237 use crate::{encode, Encodable};
238 use core::fmt::Debug;
239 use hex_literal::hex;
240
241 #[allow(unused_imports)]
242 use alloc::{string::String, vec::Vec};
243
244 fn check_decode<'a, T, IT>(fixtures: IT)
245 where
246 T: Encodable + Decodable + PartialEq + Debug,
247 IT: IntoIterator<Item = (Result<T>, &'a [u8])>,
248 {
249 for (expected, mut input) in fixtures {
250 if let Ok(expected) = &expected {
251 assert_eq!(crate::encode(expected), input, "{expected:?}");
252 }
253
254 let orig = input;
255 assert_eq!(
256 T::decode(&mut input),
257 expected,
258 "input: {}{}",
259 hex::encode(orig),
260 expected.as_ref().map_or_else(
261 |_| String::new(),
262 |expected| format!("; expected: {}", hex::encode(crate::encode(expected)))
263 )
264 );
265
266 if expected.is_ok() {
267 assert_eq!(input, &[]);
268 }
269 }
270 }
271
272 #[test]
273 fn rlp_bool() {
274 let out = [0x80];
275 let val = bool::decode(&mut &out[..]);
276 assert_eq!(Ok(false), val);
277
278 let out = [0x01];
279 let val = bool::decode(&mut &out[..]);
280 assert_eq!(Ok(true), val);
281 }
282
283 #[test]
284 fn rlp_strings() {
285 check_decode::<Bytes, _>([
286 (Ok(hex!("00")[..].to_vec().into()), &hex!("00")[..]),
287 (
288 Ok(hex!("6f62636465666768696a6b6c6d")[..].to_vec().into()),
289 &hex!("8D6F62636465666768696A6B6C6D")[..],
290 ),
291 (Err(Error::UnexpectedList), &hex!("C0")[..]),
292 ])
293 }
294
295 #[test]
296 fn rlp_fixed_length() {
297 check_decode([
298 (Ok(hex!("6f62636465666768696a6b6c6d")), &hex!("8D6F62636465666768696A6B6C6D")[..]),
299 (Err(Error::UnexpectedLength), &hex!("8C6F62636465666768696A6B6C")[..]),
300 (Err(Error::UnexpectedLength), &hex!("8E6F62636465666768696A6B6C6D6E")[..]),
301 ])
302 }
303
304 #[test]
305 fn rlp_u64() {
306 check_decode([
307 (Ok(9_u64), &hex!("09")[..]),
308 (Ok(0_u64), &hex!("80")[..]),
309 (Ok(0x0505_u64), &hex!("820505")[..]),
310 (Ok(0xCE05050505_u64), &hex!("85CE05050505")[..]),
311 (Err(Error::Overflow), &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..]),
312 (Err(Error::InputTooShort), &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..]),
313 (Err(Error::UnexpectedList), &hex!("C0")[..]),
314 (Err(Error::LeadingZero), &hex!("00")[..]),
315 (Err(Error::NonCanonicalSingleByte), &hex!("8105")[..]),
316 (Err(Error::LeadingZero), &hex!("8200F4")[..]),
317 (Err(Error::NonCanonicalSize), &hex!("B8020004")[..]),
318 (
319 Err(Error::Overflow),
320 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
321 ),
322 ])
323 }
324
325 #[test]
326 fn rlp_vectors() {
327 check_decode::<Vec<u64>, _>([
328 (Ok(vec![]), &hex!("C0")[..]),
329 (Ok(vec![0xBBCCB5_u64, 0xFFC0B5_u64]), &hex!("C883BBCCB583FFC0B5")[..]),
330 ])
331 }
332
333 #[cfg(feature = "std")]
334 #[test]
335 fn rlp_ip() {
336 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
337
338 let localhost4 = Ipv4Addr::new(127, 0, 0, 1);
339 let localhost6 = localhost4.to_ipv6_mapped();
340 let expected4 = &hex!("847F000001")[..];
341 let expected6 = &hex!("9000000000000000000000ffff7f000001")[..];
342 check_decode::<Ipv4Addr, _>([(Ok(localhost4), expected4)]);
343 check_decode::<Ipv6Addr, _>([(Ok(localhost6), expected6)]);
344 check_decode::<IpAddr, _>([
345 (Ok(IpAddr::V4(localhost4)), expected4),
346 (Ok(IpAddr::V6(localhost6)), expected6),
347 ]);
348 }
349
350 #[test]
351 fn malformed_rlp() {
352 check_decode::<Bytes, _>([
353 (Err(Error::InputTooShort), &hex!("C1")[..]),
354 (Err(Error::InputTooShort), &hex!("D7")[..]),
355 ]);
356 check_decode::<[u8; 5], _>([
357 (Err(Error::InputTooShort), &hex!("C1")[..]),
358 (Err(Error::InputTooShort), &hex!("D7")[..]),
359 ]);
360 #[cfg(feature = "std")]
361 check_decode::<std::net::IpAddr, _>([
362 (Err(Error::InputTooShort), &hex!("C1")[..]),
363 (Err(Error::InputTooShort), &hex!("D7")[..]),
364 ]);
365 check_decode::<Vec<u8>, _>([
366 (Err(Error::InputTooShort), &hex!("C1")[..]),
367 (Err(Error::InputTooShort), &hex!("D7")[..]),
368 ]);
369 check_decode::<String, _>([
370 (Err(Error::InputTooShort), &hex!("C1")[..]),
371 (Err(Error::InputTooShort), &hex!("D7")[..]),
372 ]);
373 check_decode::<String, _>([
374 (Err(Error::InputTooShort), &hex!("C1")[..]),
375 (Err(Error::InputTooShort), &hex!("D7")[..]),
376 ]);
377 check_decode::<u8, _>([(Err(Error::InputTooShort), &hex!("82")[..])]);
378 check_decode::<u64, _>([(Err(Error::InputTooShort), &hex!("82")[..])]);
379 }
380
381 #[test]
382 fn rlp_full() {
383 fn check_decode_exact<T: Decodable + Encodable + PartialEq + Debug>(input: T) {
384 let encoded = encode(&input);
385 assert_eq!(decode_exact::<T>(&encoded), Ok(input));
386 assert_eq!(
387 decode_exact::<T>([encoded, vec![0x00]].concat()),
388 Err(Error::UnexpectedLength)
389 );
390 }
391
392 check_decode_exact::<String>("".into());
393 check_decode_exact::<String>("test1234".into());
394 check_decode_exact::<Vec<u64>>(vec![]);
395 check_decode_exact::<Vec<u64>>(vec![0; 4]);
396 }
397}