rlp/
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 bytes::{Bytes, BytesMut};
12use core::{
13	iter::{empty, once},
14	mem, str,
15};
16
17use crate::{
18	error::DecoderError,
19	rlpin::Rlp,
20	stream::RlpStream,
21	traits::{Decodable, Encodable},
22};
23
24pub fn decode_usize(bytes: &[u8]) -> Result<usize, DecoderError> {
25	match bytes.len() {
26		l if l <= mem::size_of::<usize>() => {
27			if bytes[0] == 0 {
28				return Err(DecoderError::RlpInvalidIndirection)
29			}
30			let mut res = 0usize;
31			for (i, byte) in bytes.iter().enumerate().take(l) {
32				let shift = (l - 1 - i) * 8;
33				res += (*byte as usize) << shift;
34			}
35			Ok(res)
36		},
37		_ => Err(DecoderError::RlpIsTooBig),
38	}
39}
40
41impl<T: Encodable + ?Sized> Encodable for Box<T> {
42	fn rlp_append(&self, s: &mut RlpStream) {
43		Encodable::rlp_append(&**self, s)
44	}
45}
46
47impl<T: Decodable> Decodable for Box<T> {
48	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
49		T::decode(rlp).map(Box::new)
50	}
51}
52
53impl Encodable for bool {
54	fn rlp_append(&self, s: &mut RlpStream) {
55		let as_uint = u8::from(*self);
56		Encodable::rlp_append(&as_uint, s);
57	}
58}
59
60impl Decodable for bool {
61	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
62		let as_uint = <u8 as Decodable>::decode(rlp)?;
63		match as_uint {
64			0 => Ok(false),
65			1 => Ok(true),
66			_ => Err(DecoderError::Custom("invalid boolean value")),
67		}
68	}
69}
70
71impl<'a> Encodable for &'a [u8] {
72	fn rlp_append(&self, s: &mut RlpStream) {
73		s.encoder().encode_value(self);
74	}
75}
76
77impl Encodable for Vec<u8> {
78	fn rlp_append(&self, s: &mut RlpStream) {
79		s.encoder().encode_value(self);
80	}
81}
82
83impl Decodable for Vec<u8> {
84	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
85		rlp.decoder().decode_value(|bytes| Ok(bytes.to_vec()))
86	}
87}
88
89impl Encodable for Bytes {
90	fn rlp_append(&self, s: &mut RlpStream) {
91		s.encoder().encode_value(self);
92	}
93}
94
95impl Decodable for Bytes {
96	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
97		rlp.decoder().decode_value(|bytes| Ok(Bytes::copy_from_slice(bytes)))
98	}
99}
100
101impl Encodable for BytesMut {
102	fn rlp_append(&self, s: &mut RlpStream) {
103		s.encoder().encode_value(self);
104	}
105}
106
107impl Decodable for BytesMut {
108	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
109		rlp.decoder().decode_value(|bytes| Ok(bytes.into()))
110	}
111}
112
113impl<T> Encodable for Option<T>
114where
115	T: Encodable,
116{
117	fn rlp_append(&self, s: &mut RlpStream) {
118		match *self {
119			None => {
120				s.begin_list(0);
121			},
122			Some(ref value) => {
123				s.begin_list(1);
124				s.append(value);
125			},
126		}
127	}
128}
129
130impl<T> Decodable for Option<T>
131where
132	T: Decodable,
133{
134	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
135		let items = rlp.item_count()?;
136		match items {
137			1 => rlp.val_at(0).map(Some),
138			0 => Ok(None),
139			_ => Err(DecoderError::RlpIncorrectListLen),
140		}
141	}
142}
143
144impl Encodable for u8 {
145	fn rlp_append(&self, s: &mut RlpStream) {
146		if *self != 0 {
147			s.encoder().encode_iter(once(*self));
148		} else {
149			s.encoder().encode_iter(empty());
150		}
151	}
152}
153
154impl Decodable for u8 {
155	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
156		rlp.decoder().decode_value(|bytes| match bytes.len() {
157			1 if bytes[0] != 0 => Ok(bytes[0]),
158			0 => Ok(0),
159			1 => Err(DecoderError::RlpInvalidIndirection),
160			_ => Err(DecoderError::RlpIsTooBig),
161		})
162	}
163}
164
165macro_rules! impl_encodable_for_u {
166	($name: ident) => {
167		impl Encodable for $name {
168			fn rlp_append(&self, s: &mut RlpStream) {
169				let leading_empty_bytes = self.leading_zeros() as usize / 8;
170				let buffer = self.to_be_bytes();
171				s.encoder().encode_value(&buffer[leading_empty_bytes..]);
172			}
173		}
174	};
175}
176
177macro_rules! impl_decodable_for_u {
178	($name: ident) => {
179		impl Decodable for $name {
180			fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
181				rlp.decoder().decode_value(|bytes| match bytes.len() {
182					0 | 1 => u8::decode(rlp).map(|v| v as $name),
183					l if l <= mem::size_of::<$name>() => {
184						if bytes[0] == 0 {
185							return Err(DecoderError::RlpInvalidIndirection)
186						}
187						let mut res = 0 as $name;
188						for (i, byte) in bytes.iter().enumerate().take(l) {
189							let shift = (l - 1 - i) * 8;
190							res += (*byte as $name) << shift;
191						}
192						Ok(res)
193					},
194					_ => Err(DecoderError::RlpIsTooBig),
195				})
196			}
197		}
198	};
199}
200
201impl_encodable_for_u!(u16);
202impl_encodable_for_u!(u32);
203impl_encodable_for_u!(u64);
204impl_encodable_for_u!(u128);
205
206impl_decodable_for_u!(u16);
207impl_decodable_for_u!(u32);
208impl_decodable_for_u!(u64);
209impl_decodable_for_u!(u128);
210
211impl Encodable for usize {
212	fn rlp_append(&self, s: &mut RlpStream) {
213		(*self as u64).rlp_append(s);
214	}
215}
216
217impl Decodable for usize {
218	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
219		u64::decode(rlp).map(|value| value as usize)
220	}
221}
222
223impl<'a> Encodable for &'a str {
224	fn rlp_append(&self, s: &mut RlpStream) {
225		s.encoder().encode_value(self.as_bytes());
226	}
227}
228
229impl Encodable for String {
230	fn rlp_append(&self, s: &mut RlpStream) {
231		s.encoder().encode_value(self.as_bytes());
232	}
233}
234
235impl Decodable for String {
236	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
237		rlp.decoder().decode_value(|bytes| {
238			match str::from_utf8(bytes) {
239				Ok(s) => Ok(s.to_owned()),
240				// consider better error type here
241				Err(_err) => Err(DecoderError::RlpExpectedToBeData),
242			}
243		})
244	}
245}