rlp_decoder/
impls.rs

1// Copyright 2020 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9#[cfg(not(feature = "std"))]
10use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
11use core::{
12	mem, str,
13};
14
15use crate::{
16	error::DecoderError,
17	rlpin::Rlp,
18	traits::Decodable,
19};
20
21pub fn decode_usize(bytes: &[u8]) -> Result<usize, DecoderError> {
22	match bytes.len() {
23		l if l <= mem::size_of::<usize>() => {
24			if bytes[0] == 0 {
25				return Err(DecoderError::RlpInvalidIndirection)
26			}
27			let mut res = 0usize;
28			for (i, byte) in bytes.iter().enumerate().take(l) {
29				let shift = (l - 1 - i) * 8;
30				res += (*byte as usize) << shift;
31			}
32			Ok(res)
33		},
34		_ => Err(DecoderError::RlpIsTooBig),
35	}
36}
37
38impl<T: Decodable> Decodable for Box<T> {
39	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
40		T::decode(rlp).map(Box::new)
41	}
42}
43
44impl Decodable for bool {
45	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
46		let as_uint = <u8 as Decodable>::decode(rlp)?;
47		match as_uint {
48			0 => Ok(false),
49			1 => Ok(true),
50			_ => Err(DecoderError::Custom("invalid boolean value")),
51		}
52	}
53}
54
55impl Decodable for Vec<u8> {
56	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
57		rlp.decoder().decode_value(|bytes| Ok(bytes.to_vec()))
58	}
59}
60
61// impl Decodable for Bytes {
62// 	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
63// 		rlp.decoder().decode_value(|bytes| Ok(Bytes::copy_from_slice(bytes)))
64// 	}
65// }
66
67// impl Decodable for BytesMut {
68// 	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
69// 		rlp.decoder().decode_value(|bytes| Ok(bytes.into()))
70// 	}
71// }
72
73impl<T> Decodable for Option<T>
74where
75	T: Decodable,
76{
77	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
78		let items = rlp.item_count()?;
79		match items {
80			1 => rlp.val_at(0).map(Some),
81			0 => Ok(None),
82			_ => Err(DecoderError::RlpIncorrectListLen),
83		}
84	}
85}
86
87impl Decodable for u8 {
88	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
89		rlp.decoder().decode_value(|bytes| match bytes.len() {
90			1 if bytes[0] != 0 => Ok(bytes[0]),
91			0 => Ok(0),
92			1 => Err(DecoderError::RlpInvalidIndirection),
93			_ => Err(DecoderError::RlpIsTooBig),
94		})
95	}
96}
97
98macro_rules! impl_decodable_for_u {
99	($name: ident) => {
100		impl Decodable for $name {
101			fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
102				rlp.decoder().decode_value(|bytes| match bytes.len() {
103					0 | 1 => u8::decode(rlp).map(|v| v as $name),
104					l if l <= mem::size_of::<$name>() => {
105						if bytes[0] == 0 {
106							return Err(DecoderError::RlpInvalidIndirection)
107						}
108						let mut res = 0 as $name;
109						for (i, byte) in bytes.iter().enumerate().take(l) {
110							let shift = (l - 1 - i) * 8;
111							res += (*byte as $name) << shift;
112						}
113						Ok(res)
114					},
115					_ => Err(DecoderError::RlpIsTooBig),
116				})
117			}
118		}
119	};
120}
121
122impl_decodable_for_u!(u16);
123impl_decodable_for_u!(u32);
124impl_decodable_for_u!(u64);
125impl_decodable_for_u!(u128);
126
127impl Decodable for usize {
128	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
129		u64::decode(rlp).map(|value| value as usize)
130	}
131}
132
133impl Decodable for String {
134	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
135		rlp.decoder().decode_value(|bytes| {
136			match str::from_utf8(bytes) {
137				Ok(s) => Ok(s.to_owned()),
138				// consider better error type here
139				Err(_err) => Err(DecoderError::RlpExpectedToBeData),
140			}
141		})
142	}
143}