use std::cmp;
use utils::crypto::hash::{Digest, Hash};
use errors::common::CommonError;
pub use services::ledger::merkletree::proof::{
Proof,
Lemma,
Positioned
};
pub type TreeLeafData = String;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Tree {
Empty {
hash: Vec<u8>
},
Leaf {
hash: Vec<u8>,
value: TreeLeafData
},
Node {
hash: Vec<u8>,
left: Box<Tree>,
right: Box<Tree>
}
}
impl Tree {
pub fn empty(hash: Digest) -> Self {
Tree::Empty {
hash: hash.to_vec()
}
}
pub fn new(hash: Digest, value: TreeLeafData) -> Self {
Tree::Leaf {
hash: hash.to_vec(),
value: value
}
}
pub fn new_leaf(value: TreeLeafData) -> Result<Tree, CommonError> {
let hash = Hash::hash_leaf(&value)?;
Ok(Tree::new(hash, value))
}
pub fn hash(&self) -> &Vec<u8> {
match *self {
Tree::Empty { ref hash } => hash,
Tree::Leaf { ref hash, .. } => hash,
Tree::Node { ref hash, .. } => hash
}
}
pub fn iter(&self) -> LeavesIterator {
LeavesIterator::new(self)
}
pub fn get_height(&self) -> usize {
match *self {
Tree::Empty { .. } => { 0 },
Tree::Node { ref left, ref right, .. } => {
1 + cmp::max(left.get_height(),right.get_height())
},
Tree::Leaf { .. } => { 0 }
}
}
pub fn get_count(&self) -> usize {
match *self {
Tree::Empty { .. } => { 0 },
Tree::Node { ref left, ref right, .. } => {
left.get_count() + right.get_count()
},
Tree::Leaf { .. } => { 1 }
}
}
}
#[allow(missing_debug_implementations)]
pub struct LeavesIterator<'a> {
current_value: Option<&'a TreeLeafData>,
right_nodes: Vec<&'a Tree>
}
impl <'a> LeavesIterator<'a> {
fn new(root: &'a Tree) -> Self {
let mut iter = LeavesIterator {
current_value: None,
right_nodes: Vec::new()
};
iter.add_left(root);
iter
}
fn add_left(&mut self, mut tree: &'a Tree) {
loop {
match *tree {
Tree::Empty { .. } => {
self.current_value = None;
break;
},
Tree::Node { ref left, ref right, .. } => {
self.right_nodes.push(right);
tree = left;
},
Tree::Leaf { ref value, .. } => {
self.current_value = Some(value);
break;
}
}
}
}
}
impl <'a> Iterator for LeavesIterator<'a> {
type Item = &'a TreeLeafData;
fn next(&mut self) -> Option<&'a TreeLeafData> {
let result = self.current_value.take();
if let Some(rest) = self.right_nodes.pop() {
self.add_left(rest);
}
result
}
}
#[allow(missing_debug_implementations)]
pub struct LeavesIntoIterator {
current_value: Option<TreeLeafData>,
right_nodes: Vec<Tree>
}
impl LeavesIntoIterator {
fn new(root: Tree) -> Self {
let mut iter = LeavesIntoIterator {
current_value: None,
right_nodes: Vec::new()
};
iter.add_left(root);
iter
}
fn add_left(&mut self, mut tree: Tree) {
loop {
match tree {
Tree::Empty { .. } => {
self.current_value = None;
break;
},
Tree::Node { left, right, .. } => {
self.right_nodes.push(*right);
tree = *left;
},
Tree::Leaf { value, .. } => {
self.current_value = Some(value);
break;
}
}
}
}
}
impl Iterator for LeavesIntoIterator {
type Item = TreeLeafData;
fn next(&mut self) -> Option<TreeLeafData> {
let result = self.current_value.take();
if let Some(rest) = self.right_nodes.pop() {
self.add_left(rest);
}
result
}
}
impl IntoIterator for Tree {
type Item = TreeLeafData;
type IntoIter = LeavesIntoIterator;
fn into_iter(self) -> Self::IntoIter {
LeavesIntoIterator::new(self)
}
}