1use crate::types::Header;
2use arrayvec::ArrayVec;
3use bytes::{Buf, Bytes, BytesMut};
4use core::{any::Any, num::NonZeroUsize};
5
6pub trait Decodable: Sized {
7 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError>;
8}
9
10#[cfg(feature = "alloc")]
11mod alloc_impl {
12 use super::*;
13
14 impl<T> Decodable for ::alloc::boxed::Box<T>
15 where
16 T: Decodable + Sized,
17 {
18 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
19 T::decode(buf).map(::alloc::boxed::Box::new)
20 }
21 }
22
23 impl<T> Decodable for ::alloc::sync::Arc<T>
24 where
25 T: Decodable + Sized,
26 {
27 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
28 T::decode(buf).map(::alloc::sync::Arc::new)
29 }
30 }
31
32 impl Decodable for ::alloc::string::String {
33 fn decode(from: &mut &[u8]) -> Result<Self, DecodeError> {
34 let h = Header::decode(from)?;
35 if h.list {
36 return Err(DecodeError::UnexpectedList);
37 }
38 let mut to = ::alloc::vec::Vec::with_capacity(h.payload_length);
39 to.extend_from_slice(&from[..h.payload_length]);
40 from.advance(h.payload_length);
41
42 Self::from_utf8(to).map_err(|_| DecodeError::Custom("invalid string"))
43 }
44 }
45
46 impl<T> Decodable for ::alloc::vec::Vec<T>
47 where
48 T: Decodable + 'static,
49 {
50 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
51 let h = Header::decode(buf)?;
52
53 let mut to = ::alloc::vec::Vec::new();
54 if let Some(to) = <dyn Any>::downcast_mut::<::alloc::vec::Vec<u8>>(&mut to) {
55 if h.list {
56 return Err(DecodeError::UnexpectedList);
57 }
58 to.extend_from_slice(&buf[..h.payload_length]);
59 buf.advance(h.payload_length);
60 } else {
61 if !h.list {
62 return Err(DecodeError::UnexpectedString);
63 }
64
65 let payload_view = &mut &buf[..h.payload_length];
66
67 while !payload_view.is_empty() {
68 to.push(T::decode(payload_view)?);
69 }
70
71 buf.advance(h.payload_length);
72 }
73
74 Ok(to)
75 }
76 }
77}
78
79#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub enum DecodeError {
81 Overflow,
82 LeadingZero,
83 InputTooShort { needed: Option<NonZeroUsize> },
84 NonCanonicalSingleByte,
85 NonCanonicalSize,
86 UnexpectedLength,
87 UnexpectedString,
88 UnexpectedList,
89 ListLengthMismatch { expected: usize, got: usize },
90 Custom(&'static str),
91}
92
93#[cfg(feature = "std")]
94impl std::error::Error for DecodeError {}
95
96impl core::fmt::Display for DecodeError {
97 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
98 match self {
99 DecodeError::Overflow => write!(f, "overflow"),
100 DecodeError::LeadingZero => write!(f, "leading zero"),
101 DecodeError::InputTooShort { needed } => {
102 write!(f, "input too short")?;
103 if let Some(needed) = needed {
104 write!(f, ": need {needed} more bytes")?;
105 }
106
107 Ok(())
108 }
109 DecodeError::NonCanonicalSingleByte => write!(f, "non-canonical single byte"),
110 DecodeError::NonCanonicalSize => write!(f, "non-canonical size"),
111 DecodeError::UnexpectedLength => write!(f, "unexpected length"),
112 DecodeError::UnexpectedString => write!(f, "unexpected string"),
113 DecodeError::UnexpectedList => write!(f, "unexpected list"),
114 DecodeError::ListLengthMismatch { expected, got } => {
115 write!(f, "list length mismatch: expected {expected}, got {got}")
116 }
117 DecodeError::Custom(err) => write!(f, "{err}"),
118 }
119 }
120}
121
122impl Header {
123 pub fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
124 if !buf.has_remaining() {
125 return Err(DecodeError::InputTooShort { needed: None });
126 }
127
128 let b = buf[0];
129 let h: Self = {
130 if b < 0x80 {
131 Self {
132 list: false,
133 payload_length: 1,
134 }
135 } else if b < 0xB8 {
136 buf.advance(1);
137 let h = Self {
138 list: false,
139 payload_length: b as usize - 0x80,
140 };
141
142 if h.payload_length == 1 {
143 if !buf.has_remaining() {
144 return Err(DecodeError::InputTooShort { needed: None });
145 }
146 if buf[0] < 0x80 {
147 return Err(DecodeError::NonCanonicalSingleByte);
148 }
149 }
150
151 h
152 } else if b < 0xC0 {
153 buf.advance(1);
154 let len_of_len = b as usize - 0xB7;
155 if let Some(needed) = len_of_len
156 .checked_sub(buf.len())
157 .and_then(NonZeroUsize::new)
158 {
159 return Err(DecodeError::InputTooShort {
160 needed: Some(needed),
161 });
162 }
163 let payload_length = usize::try_from(u64::from_be_bytes(
164 static_left_pad(&buf[..len_of_len]).ok_or(DecodeError::LeadingZero)?,
165 ))
166 .map_err(|_| DecodeError::Custom("Input too big"))?;
167 buf.advance(len_of_len);
168 if payload_length < 56 {
169 return Err(DecodeError::NonCanonicalSize);
170 }
171
172 Self {
173 list: false,
174 payload_length,
175 }
176 } else if b < 0xF8 {
177 buf.advance(1);
178 Self {
179 list: true,
180 payload_length: b as usize - 0xC0,
181 }
182 } else {
183 buf.advance(1);
184 let list = true;
185 let len_of_len = b as usize - 0xF7;
186 if let Some(needed) = len_of_len
187 .checked_sub(buf.len())
188 .and_then(NonZeroUsize::new)
189 {
190 return Err(DecodeError::InputTooShort {
191 needed: Some(needed),
192 });
193 }
194 let payload_length = usize::try_from(u64::from_be_bytes(
195 static_left_pad(&buf[..len_of_len]).ok_or(DecodeError::LeadingZero)?,
196 ))
197 .map_err(|_| DecodeError::Custom("Input too big"))?;
198 buf.advance(len_of_len);
199 if payload_length < 56 {
200 return Err(DecodeError::NonCanonicalSize);
201 }
202
203 Self {
204 list,
205 payload_length,
206 }
207 }
208 };
209
210 if let Some(needed) = h
211 .payload_length
212 .checked_sub(buf.remaining())
213 .and_then(NonZeroUsize::new)
214 {
215 return Err(DecodeError::InputTooShort {
216 needed: Some(needed),
217 });
218 }
219
220 Ok(h)
221 }
222}
223
224fn static_left_pad<const LEN: usize>(data: &[u8]) -> Option<[u8; LEN]> {
225 if data.len() > LEN {
226 return None;
227 }
228
229 let mut v = [0; LEN];
230
231 if data.is_empty() {
232 return Some(v);
233 }
234
235 if data[0] == 0 {
236 return None;
237 }
238
239 v[LEN - data.len()..].copy_from_slice(data);
240 Some(v)
241}
242
243macro_rules! decode_integer {
244 ($t:ty) => {
245 impl Decodable for $t {
246 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
247 let h = Header::decode(buf)?;
248 if h.list {
249 return Err(DecodeError::UnexpectedList);
250 }
251 if h.payload_length > (<$t>::BITS as usize / 8) {
252 return Err(DecodeError::Overflow);
253 }
254 if let Some(needed) = h
255 .payload_length
256 .checked_sub(buf.remaining())
257 .and_then(NonZeroUsize::new)
258 {
259 return Err(DecodeError::InputTooShort {
260 needed: Some(needed),
261 });
262 }
263 let v = <$t>::from_be_bytes(
264 static_left_pad(&buf[..h.payload_length]).ok_or(DecodeError::LeadingZero)?,
265 );
266 buf.advance(h.payload_length);
267 Ok(v)
268 }
269 }
270 };
271}
272
273decode_integer!(usize);
274decode_integer!(u8);
275decode_integer!(u16);
276decode_integer!(u32);
277decode_integer!(u64);
278decode_integer!(u128);
279
280impl Decodable for bool {
281 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
282 Ok(match u8::decode(buf)? {
283 0 => false,
284 1 => true,
285 _ => return Err(DecodeError::Custom("invalid bool value, must be 0 or 1")),
286 })
287 }
288}
289
290#[cfg(feature = "ethnum")]
291decode_integer!(ethnum::U256);
292
293#[cfg(feature = "ethereum-types")]
294mod ethereum_types_support {
295 use super::*;
296 use ethereum_types::*;
297
298 macro_rules! fixed_hash_impl {
299 ($t:ty) => {
300 impl Decodable for $t {
301 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
302 Decodable::decode(buf).map(Self)
303 }
304 }
305 };
306 }
307
308 fixed_hash_impl!(H64);
309 fixed_hash_impl!(H128);
310 fixed_hash_impl!(H160);
311 fixed_hash_impl!(H256);
312 fixed_hash_impl!(H512);
313 fixed_hash_impl!(H520);
314 #[cfg(feature = "ethbloom")]
315 fixed_hash_impl!(Bloom);
316
317 macro_rules! fixed_uint_impl {
318 ($t:ty, $n_bytes:tt) => {
319 impl Decodable for $t {
320 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
321 let h = Header::decode(buf)?;
322 if h.list {
323 return Err(DecodeError::UnexpectedList);
324 }
325 if h.payload_length > $n_bytes {
326 return Err(DecodeError::Overflow);
327 }
328 if let Some(needed) = h
329 .payload_length
330 .checked_sub(buf.remaining())
331 .and_then(NonZeroUsize::new)
332 {
333 return Err(DecodeError::InputTooShort {
334 needed: Some(needed),
335 });
336 }
337 let n = <$t>::from_big_endian(
338 &static_left_pad::<$n_bytes>(&buf[..h.payload_length])
339 .ok_or(DecodeError::LeadingZero)?,
340 );
341 buf.advance(h.payload_length);
342 Ok(n)
343 }
344 }
345 };
346 }
347
348 fixed_uint_impl!(U64, 8);
349 fixed_uint_impl!(U128, 16);
350 fixed_uint_impl!(U256, 32);
351 fixed_uint_impl!(U512, 64);
352}
353
354impl<T, const LEN: usize> Decodable for [T; LEN]
355where
356 T: Decodable + 'static,
357{
358 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
359 ArrayVec::<T, LEN>::decode(buf)?
360 .into_inner()
361 .map_err(|arr| DecodeError::ListLengthMismatch {
362 expected: LEN,
363 got: arr.len(),
364 })
365 }
366}
367
368impl Decodable for BytesMut {
369 fn decode(from: &mut &[u8]) -> Result<Self, DecodeError> {
370 let h = Header::decode(from)?;
371 if h.list {
372 return Err(DecodeError::UnexpectedList);
373 }
374 let mut to = BytesMut::with_capacity(h.payload_length);
375 to.extend_from_slice(&from[..h.payload_length]);
376 from.advance(h.payload_length);
377
378 Ok(to)
379 }
380}
381
382impl Decodable for Bytes {
383 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
384 BytesMut::decode(buf).map(BytesMut::freeze)
385 }
386}
387
388pub struct Rlp<'a> {
389 payload_view: &'a [u8],
390}
391
392impl<'a> Rlp<'a> {
393 pub fn new(mut payload: &'a [u8]) -> Result<Self, DecodeError> {
394 let h = Header::decode(&mut payload)?;
395 if !h.list {
396 return Err(DecodeError::UnexpectedString);
397 }
398
399 let payload_view = &payload[..h.payload_length];
400 Ok(Self { payload_view })
401 }
402
403 pub fn get_next<T: Decodable>(&mut self) -> Result<Option<T>, DecodeError> {
404 if self.payload_view.is_empty() {
405 return Ok(None);
406 }
407
408 Ok(Some(T::decode(&mut self.payload_view)?))
409 }
410}
411
412impl<T, const LEN: usize> Decodable for ArrayVec<T, LEN>
413where
414 T: Decodable + 'static,
415{
416 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
417 let mut arr: ArrayVec<T, LEN> = ArrayVec::new();
418 if let Some(s) = <dyn Any>::downcast_mut::<ArrayVec<u8, LEN>>(&mut arr) {
419 let h = Header::decode(buf)?;
420 if h.list {
421 return Err(DecodeError::UnexpectedList);
422 }
423 if h.payload_length != LEN {
424 return Err(DecodeError::UnexpectedLength);
425 }
426
427 s.try_extend_from_slice(&buf[..LEN]).unwrap();
428 buf.advance(LEN);
429 } else {
430 let h = Header::decode(buf)?;
431 if !h.list {
432 return Err(DecodeError::UnexpectedString);
433 }
434
435 let payload_view = &mut &buf[..h.payload_length];
436
437 while !payload_view.is_empty() {
438 if arr.try_push(T::decode(payload_view)?).is_err() {
439 return Err(DecodeError::ListLengthMismatch {
440 expected: LEN,
441 got: LEN + 1,
442 });
443 }
444 }
445
446 buf.advance(h.payload_length);
447 }
448
449 Ok(arr)
450 }
451}
452
453#[cfg(test)]
454mod tests {
455 extern crate alloc;
456
457 use super::*;
458 use alloc::vec;
459 use core::fmt::Debug;
460 use ethereum_types::{U64, U128, U256, U512};
461 use ethnum::AsU256;
462 use hex_literal::hex;
463
464 fn check_decode<T, IT>(fixtures: IT)
465 where
466 T: Decodable + PartialEq + Debug,
467 IT: IntoIterator<Item = (Result<T, DecodeError>, &'static [u8])>,
468 {
469 for (expected, mut input) in fixtures {
470 assert_eq!(T::decode(&mut input), expected);
471 if expected.is_ok() {
472 assert_eq!(input, &[]);
473 }
474 }
475 }
476
477 fn check_decode_list<T, IT>(fixtures: IT)
478 where
479 T: Decodable + PartialEq + Debug + 'static,
480 IT: IntoIterator<Item = (Result<alloc::vec::Vec<T>, DecodeError>, &'static [u8])>,
481 {
482 for (expected, mut input) in fixtures {
483 assert_eq!(vec::Vec::<T>::decode(&mut input), expected);
484 if expected.is_ok() {
485 assert_eq!(input, &[]);
486 }
487 }
488 }
489
490 #[test]
491 fn rlp_strings() {
492 check_decode::<Bytes, _>(vec![
493 (Ok((hex!("00")[..]).to_vec().into()), &hex!("00")[..]),
494 (
495 Ok((hex!("6f62636465666768696a6b6c6d")[..]).to_vec().into()),
496 &hex!("8D6F62636465666768696A6B6C6D")[..],
497 ),
498 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
499 ])
500 }
501
502 #[test]
503 fn rlp_fixed_length() {
504 check_decode(vec![
505 (
506 Ok(hex!("6f62636465666768696a6b6c6d")),
507 &hex!("8D6F62636465666768696A6B6C6D")[..],
508 ),
509 (
510 Err(DecodeError::UnexpectedLength),
511 &hex!("8C6F62636465666768696A6B6C")[..],
512 ),
513 (
514 Err(DecodeError::UnexpectedLength),
515 &hex!("8E6F62636465666768696A6B6C6D6E")[..],
516 ),
517 ])
518 }
519
520 #[test]
521 fn rlp_u64() {
522 check_decode(vec![
523 (Ok(9_u64), &hex!("09")[..]),
524 (Ok(0_u64), &hex!("80")[..]),
525 (Ok(0x0505_u64), &hex!("820505")[..]),
526 (Ok(0xCE05050505_u64), &hex!("85CE05050505")[..]),
527 (
528 Err(DecodeError::Overflow),
529 &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
530 ),
531 (
532 Err(DecodeError::InputTooShort {
533 needed: Some(NonZeroUsize::new(1).unwrap()),
534 }),
535 &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
536 ),
537 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
538 (Err(DecodeError::LeadingZero), &hex!("00")[..]),
539 (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
540 (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
541 (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
542 (
543 Err(DecodeError::Overflow),
544 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
545 ),
546 ])
547 }
548
549 #[test]
550 fn rlp_u256() {
551 check_decode(vec![
552 (Ok(9_u8.as_u256()), &hex!("09")[..]),
553 (Ok(0_u8.as_u256()), &hex!("80")[..]),
554 (Ok(0x0505_u16.as_u256()), &hex!("820505")[..]),
555 (Ok(0xCE05050505_u64.as_u256()), &hex!("85CE05050505")[..]),
556 (
557 Ok(0xFFFFFFFFFFFFFFFFFF7C_u128.as_u256()),
558 &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
559 ),
560 (
561 Err(DecodeError::InputTooShort {
562 needed: Some(NonZeroUsize::new(1).unwrap()),
563 }),
564 &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
565 ),
566 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
567 (Err(DecodeError::LeadingZero), &hex!("00")[..]),
568 (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
569 (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
570 (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
571 (
572 Err(DecodeError::Overflow),
573 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
574 ),
575 ])
576 }
577
578 #[cfg(feature = "ethereum-types")]
579 #[test]
580 fn rlp_ethereum_types_u64() {
581 check_decode(vec![
582 (Ok(U64::from(9_u8)), &hex!("09")[..]),
583 (Ok(U64::from(0_u8)), &hex!("80")[..]),
584 (Ok(U64::from(0x0505_u16)), &hex!("820505")[..]),
585 (Ok(U64::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
586 (
587 Err(DecodeError::Overflow),
588 &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
589 ),
590 (
591 Err(DecodeError::InputTooShort {
592 needed: Some(NonZeroUsize::new(1).unwrap()),
593 }),
594 &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
595 ),
596 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
597 (Err(DecodeError::LeadingZero), &hex!("00")[..]),
598 (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
599 (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
600 (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
601 (
602 Err(DecodeError::Overflow),
603 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
604 ),
605 ])
606 }
607
608 #[cfg(feature = "ethereum-types")]
609 #[test]
610 fn rlp_ethereum_types_u128() {
611 check_decode(vec![
612 (Ok(U128::from(9_u8)), &hex!("09")[..]),
613 (Ok(U128::from(0_u8)), &hex!("80")[..]),
614 (Ok(U128::from(0x0505_u16)), &hex!("820505")[..]),
615 (Ok(U128::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
616 (
617 Ok(U128::from(0xFFFFFFFFFFFFFFFFFF7C_u128)),
618 &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
619 ),
620 (
621 Err(DecodeError::InputTooShort {
622 needed: Some(NonZeroUsize::new(1).unwrap()),
623 }),
624 &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
625 ),
626 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
627 (Err(DecodeError::LeadingZero), &hex!("00")[..]),
628 (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
629 (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
630 (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
631 (
632 Err(DecodeError::Overflow),
633 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
634 ),
635 ])
636 }
637
638 #[cfg(feature = "ethereum-types")]
639 #[test]
640 fn rlp_ethereum_types_u256() {
641 check_decode(vec![
642 (Ok(U256::from(9_u8)), &hex!("09")[..]),
643 (Ok(U256::from(0_u8)), &hex!("80")[..]),
644 (Ok(U256::from(0x0505_u16)), &hex!("820505")[..]),
645 (Ok(U256::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
646 (
647 Ok(U256::from(0xFFFFFFFFFFFFFFFFFF7C_u128)),
648 &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
649 ),
650 (
651 Err(DecodeError::InputTooShort {
652 needed: Some(NonZeroUsize::new(1).unwrap()),
653 }),
654 &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
655 ),
656 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
657 (Err(DecodeError::LeadingZero), &hex!("00")[..]),
658 (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
659 (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
660 (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
661 (
662 Err(DecodeError::Overflow),
663 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
664 ),
665 ])
666 }
667
668 #[cfg(feature = "ethereum-types")]
669 #[test]
670 fn rlp_ethereum_types_u512() {
671 check_decode(vec![
672 (Ok(U512::from(9_u8)), &hex!("09")[..]),
673 (Ok(U512::from(0_u8)), &hex!("80")[..]),
674 (Ok(U512::from(0x0505_u16)), &hex!("820505")[..]),
675 (Ok(U512::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
676 (
677 Ok(U512::from(0xFFFFFFFFFFFFFFFFFF7C_u128)),
678 &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
679 ),
680 (
681 Err(DecodeError::InputTooShort{
682 needed: Some(NonZeroUsize::new(1).unwrap()),
683 }),
684 &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
685 ),
686 (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
687 (Err(DecodeError::LeadingZero), &hex!("00")[..]),
688 (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
689 (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
690 (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
691 (
692 Ok(U512::from_dec_str("115792089237316195423570985008687907853269984676653278628940326933415738736640").unwrap()),
693 &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
694 ),
695 (
696 Err(DecodeError::Overflow),
697 &hex!("B84101000000000000000000000000000000000000008B000000000000000000000000000000000000000000000000000000000000008B000000000000000000000000")[..],
698 ),
699 ])
700 }
701
702 #[test]
703 fn rlp_vectors() {
704 check_decode_list(vec![
705 (Ok(vec![]), &hex!("C0")[..]),
706 (
707 Ok(vec![0xBBCCB5_u64, 0xFFC0B5_u64]),
708 &hex!("C883BBCCB583FFC0B5")[..],
709 ),
710 ])
711 }
712
713 #[test]
714 fn vec_specialization() {
715 const SPECIALIZED: [u8; 2] = [0x42_u8, 0x43_u8];
716 const GENERAL: [u64; 2] = [0xFFCCB5_u64, 0xFFC0B5_u64];
717
718 const SPECIALIZED_EXP: &[u8] = &hex!("824243");
719 const GENERAL_EXP: &[u8] = &hex!("C883FFCCB583FFC0B5");
720
721 check_decode([(Ok(SPECIALIZED), SPECIALIZED_EXP)]);
722 check_decode([(Ok(GENERAL), GENERAL_EXP)]);
723
724 check_decode([(Ok(ArrayVec::from(SPECIALIZED)), SPECIALIZED_EXP)]);
725 check_decode([(Ok(ArrayVec::from(GENERAL)), GENERAL_EXP)]);
726
727 #[cfg(feature = "alloc")]
728 {
729 check_decode([(Ok(SPECIALIZED.to_vec()), SPECIALIZED_EXP)]);
730 check_decode([(Ok(GENERAL.to_vec()), GENERAL_EXP)]);
731 }
732 }
733}