use std::collections::VecDeque;
use serde::{Serialize, Deserialize};
use crate::{
ser::Serializer,
error::{Result, Error},
de::Deserializer
};
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
Serializer::to_bytes(value)
}
pub fn from_bytes<'a, T>(s: &'a [u8]) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::new(s);
let t = T::deserialize(&mut deserializer)?;
Ok(t)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RlpNodeValue<'de> {
Bytes(&'de [u8]),
Compound(VecDeque<RlpNode<'de>>)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RlpNode<'de> {
pub span: &'de [u8],
pub value: RlpNodeValue<'de>
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RlpTree<'de> {
root: RlpNode<'de>,
value_count: usize
}
enum TraverseRlp<'de> {
Found(&'de [u8]),
Leaf(&'de [u8]),
Empty
}
impl<'de> RlpTree<'de> {
pub fn new(buf: &'de [u8]) -> Result<Self> {
if buf.is_empty() {
return Err(Error::MalformedData)
}
let mut root = VecDeque::with_capacity(1);
let mut value_count = 0;
let de = Deserializer::new(buf);
let (tree, remained) = Self::parse_node(&mut value_count, de)?;
root.push_back(tree);
if !remained.is_empty() {
Err(Error::MalformedData)
} else {
Ok(Self {
root: RlpNode {
span: buf,
value: RlpNodeValue::Compound(root),
},
value_count
})
}
}
pub fn root(&'de self) -> &RlpNode {
if let RlpNodeValue::Compound(root) = &self.root.value {
root.front().unwrap()
} else {
panic!("No root node: Tree is empty.")
}
}
pub fn root_mut(&'de mut self) -> &mut RlpNode {
if let RlpNodeValue::Compound(root) = &mut self.root.value {
root.front_mut().unwrap()
} else {
panic!("No root node: Tree is empty.")
}
}
pub fn value_count(&self) -> usize {
self.value_count
}
fn parse_node(counter: &mut usize, de: Deserializer<'de>) -> Result<(RlpNode<'de>, Deserializer<'de>)> {
if de.next_is_bytes() {
*counter += 1;
Self::extract_bytes(de)
} else {
Self::extract_seq(counter, de)
}
}
fn extract_bytes(de: Deserializer<'de>) -> Result<(RlpNode<'de>, Deserializer<'de>)> {
let (span, bytes, new) = de.next_bytes()?;
Ok((RlpNode {
span,
value: RlpNodeValue::Bytes(bytes)
}, new))
}
fn extract_seq(counter: &mut usize, de: Deserializer<'de>) -> Result<(RlpNode<'de>, Deserializer<'de>)> {
let (span, mut seq, remained) = de.next_seq()?;
let mut nodes = VecDeque::new();
while !seq.is_empty() {
let (node, remained) = Self::parse_node(counter, seq)?;
seq = remained;
nodes.push_back(node);
}
Ok((RlpNode {
span,
value: RlpNodeValue::Compound(nodes)
}, remained))
}
fn pop_front_deep(node: Option<&mut RlpNode<'de>>) -> TraverseRlp<'de> {
let node = if let Some(node) = node {
node
} else {
return TraverseRlp::Empty
};
match &mut node.value {
RlpNodeValue::Bytes(bytes) => TraverseRlp::Leaf(bytes),
RlpNodeValue::Compound(compound) => {
loop {
match Self::pop_front_deep(compound.front_mut()) {
TraverseRlp::Empty => {
if !compound.is_empty() {
compound.pop_front().unwrap();
continue;
}
return TraverseRlp::Empty
},
TraverseRlp::Leaf(bytes) => {
compound.pop_front().unwrap();
return TraverseRlp::Found(bytes)
},
TraverseRlp::Found(bytes) => {
return TraverseRlp::Found(bytes)
}
}
}
}
}
}
}
impl<'de> Iterator for RlpTree<'de> {
type Item = &'de [u8];
fn next(&mut self) -> Option<&'de [u8]> {
if self.value_count == 0 {
return None
}
self.value_count -= 1;
match Self::pop_front_deep(Some(&mut self.root)) {
TraverseRlp::Found(bytes) => Some(bytes),
_ => unreachable!()
}
}
}