use super::{
decode::{RLPDecode, decode_rlp_item, get_item_with_prefix},
encode::{RLPEncode, encode_length},
error::RLPDecodeError,
};
use alloc::format;
use alloc::vec::Vec;
use bytes::BufMut;
use bytes::Bytes;
#[derive(Debug)]
#[must_use = "`Decoder` must be consumed with `finish` to perform decoding checks"]
pub struct Decoder<'a> {
payload: &'a [u8],
remaining: &'a [u8],
}
impl<'a> Decoder<'a> {
pub fn new(buf: &'a [u8]) -> Result<Self, RLPDecodeError> {
match decode_rlp_item(buf)? {
(true, payload, remaining) => Ok(Self { payload, remaining }),
(false, _, _) => Err(RLPDecodeError::UnexpectedString),
}
}
pub fn decode_field<T: RLPDecode>(self, name: &str) -> Result<(T, Self), RLPDecodeError> {
let (field, rest) = <T as RLPDecode>::decode_unfinished(self.payload)
.map_err(|err| field_decode_error::<T>(name, err))?;
let updated_self = Self {
payload: rest,
..self
};
Ok((field, updated_self))
}
pub fn get_encoded_item(self) -> Result<(Vec<u8>, Self), RLPDecodeError> {
self.get_encoded_item_ref()
.map(|(field, updated_self)| (field.to_vec(), updated_self))
}
pub fn get_encoded_item_ref(self) -> Result<(&'a [u8], Self), RLPDecodeError> {
get_item_with_prefix(self.payload).map(|(field, rest)| {
let updated_self = Self {
payload: rest,
..self
};
(field, updated_self)
})
}
pub fn decode_optional_field<T: RLPDecode>(self) -> (Option<T>, Self) {
match <T as RLPDecode>::decode_unfinished(self.payload) {
Ok((field, rest)) => {
let updated_self = Self {
payload: rest,
..self
};
(Some(field), updated_self)
}
Err(_) => (None, self),
}
}
pub const fn finish(self) -> Result<&'a [u8], RLPDecodeError> {
if self.payload.is_empty() {
Ok(self.remaining)
} else {
Err(RLPDecodeError::MalformedData)
}
}
pub const fn is_done(&self) -> bool {
self.payload.is_empty()
}
pub const fn finish_unchecked(self) -> &'a [u8] {
self.remaining
}
pub const fn get_payload_len(&self) -> usize {
self.payload.len()
}
}
fn field_decode_error<T>(field_name: &str, err: RLPDecodeError) -> RLPDecodeError {
let typ = core::any::type_name::<T>();
let err_msg = format!("Error decoding field '{field_name}' of type {typ}: {err}");
RLPDecodeError::Custom(err_msg)
}
#[must_use = "`Encoder` must be consumed with `finish` to perform the encoding"]
pub struct Encoder<'a> {
buf: &'a mut dyn BufMut,
temp_buf: Vec<u8>,
}
impl core::fmt::Debug for Encoder<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Encoder")
.field("buf", &"...")
.field("temp_buf", &self.temp_buf)
.finish()
}
}
impl<'a> Encoder<'a> {
pub fn new(buf: &'a mut dyn BufMut) -> Self {
Self {
buf,
temp_buf: Default::default(),
}
}
pub fn encode_field<T: RLPEncode>(mut self, value: &T) -> Self {
<T as RLPEncode>::encode(value, &mut self.temp_buf);
self
}
pub fn encode_optional_field<T: RLPEncode>(mut self, opt_value: &Option<T>) -> Self {
if let Some(value) = opt_value {
<T as RLPEncode>::encode(value, &mut self.temp_buf);
}
self
}
pub fn encode_key_value_list<T: RLPEncode>(mut self, list: &Vec<(Bytes, Bytes)>) -> Self {
for (key, value) in list {
<Bytes>::encode(key, &mut self.temp_buf);
self.temp_buf.put_slice(value);
}
self
}
pub fn finish(self) {
encode_length(self.temp_buf.len(), self.buf);
self.buf.put_slice(&self.temp_buf);
}
pub fn encode_raw(mut self, value: &[u8]) -> Self {
self.temp_buf.put_slice(value);
self
}
pub fn encode_bytes(mut self, value: &[u8]) -> Self {
<[u8] as RLPEncode>::encode(value, &mut self.temp_buf);
self
}
}