#[cfg(not(feature = "std"))]
use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
use bytes::{Bytes, BytesMut};
use core::{
iter::{empty, once},
mem, str,
};
use crate::{
error::DecoderError,
rlpin::Rlp,
stream::RlpStream,
traits::{Decodable, Encodable},
};
pub fn decode_usize(bytes: &[u8]) -> Result<usize, DecoderError> {
match bytes.len() {
l if l <= mem::size_of::<usize>() => {
if bytes[0] == 0 {
return Err(DecoderError::RlpInvalidIndirection)
}
let mut res = 0usize;
for (i, byte) in bytes.iter().enumerate().take(l) {
let shift = (l - 1 - i) * 8;
res += (*byte as usize) << shift;
}
Ok(res)
},
_ => Err(DecoderError::RlpIsTooBig),
}
}
impl<T: Encodable + ?Sized> Encodable for Box<T> {
fn rlp_append(&self, s: &mut RlpStream) {
Encodable::rlp_append(&**self, s)
}
}
impl<T: Decodable> Decodable for Box<T> {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
T::decode(rlp).map(Box::new)
}
}
impl Encodable for bool {
fn rlp_append(&self, s: &mut RlpStream) {
let as_uint = u8::from(*self);
Encodable::rlp_append(&as_uint, s);
}
}
impl Decodable for bool {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
let as_uint = <u8 as Decodable>::decode(rlp)?;
match as_uint {
0 => Ok(false),
1 => Ok(true),
_ => Err(DecoderError::Custom("invalid boolean value")),
}
}
}
impl<'a> Encodable for &'a [u8] {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self);
}
}
impl Encodable for Vec<u8> {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self);
}
}
impl Decodable for Vec<u8> {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| Ok(bytes.to_vec()))
}
}
impl Encodable for Bytes {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self);
}
}
impl Decodable for Bytes {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| Ok(Bytes::copy_from_slice(bytes)))
}
}
impl Encodable for BytesMut {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self);
}
}
impl Decodable for BytesMut {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| Ok(bytes.into()))
}
}
impl<T> Encodable for Option<T>
where
T: Encodable,
{
fn rlp_append(&self, s: &mut RlpStream) {
match *self {
None => {
s.begin_list(0);
},
Some(ref value) => {
s.begin_list(1);
s.append(value);
},
}
}
}
impl<T> Decodable for Option<T>
where
T: Decodable,
{
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
let items = rlp.item_count()?;
match items {
1 => rlp.val_at(0).map(Some),
0 => Ok(None),
_ => Err(DecoderError::RlpIncorrectListLen),
}
}
}
impl Encodable for u8 {
fn rlp_append(&self, s: &mut RlpStream) {
if *self != 0 {
s.encoder().encode_iter(once(*self));
} else {
s.encoder().encode_iter(empty());
}
}
}
impl Decodable for u8 {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| match bytes.len() {
1 if bytes[0] != 0 => Ok(bytes[0]),
0 => Ok(0),
1 => Err(DecoderError::RlpInvalidIndirection),
_ => Err(DecoderError::RlpIsTooBig),
})
}
}
macro_rules! impl_encodable_for_u {
($name: ident) => {
impl Encodable for $name {
fn rlp_append(&self, s: &mut RlpStream) {
let leading_empty_bytes = self.leading_zeros() as usize / 8;
let buffer = self.to_be_bytes();
s.encoder().encode_value(&buffer[leading_empty_bytes..]);
}
}
};
}
macro_rules! impl_decodable_for_u {
($name: ident) => {
impl Decodable for $name {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| match bytes.len() {
0 | 1 => u8::decode(rlp).map(|v| v as $name),
l if l <= mem::size_of::<$name>() => {
if bytes[0] == 0 {
return Err(DecoderError::RlpInvalidIndirection)
}
let mut res = 0 as $name;
for (i, byte) in bytes.iter().enumerate().take(l) {
let shift = (l - 1 - i) * 8;
res += (*byte as $name) << shift;
}
Ok(res)
},
_ => Err(DecoderError::RlpIsTooBig),
})
}
}
};
}
impl_encodable_for_u!(u16);
impl_encodable_for_u!(u32);
impl_encodable_for_u!(u64);
impl_encodable_for_u!(u128);
impl_decodable_for_u!(u16);
impl_decodable_for_u!(u32);
impl_decodable_for_u!(u64);
impl_decodable_for_u!(u128);
impl Encodable for usize {
fn rlp_append(&self, s: &mut RlpStream) {
(*self as u64).rlp_append(s);
}
}
impl Decodable for usize {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
u64::decode(rlp).map(|value| value as usize)
}
}
impl<'a> Encodable for &'a str {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self.as_bytes());
}
}
impl Encodable for String {
fn rlp_append(&self, s: &mut RlpStream) {
s.encoder().encode_value(self.as_bytes());
}
}
impl Decodable for String {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
rlp.decoder().decode_value(|bytes| {
match str::from_utf8(bytes) {
Ok(s) => Ok(s.to_owned()),
Err(_err) => Err(DecoderError::RlpExpectedToBeData),
}
})
}
}