mod builder;
pub use self::builder::{BuildResult, Builder, EmptyTree};
#[cfg(feature = "parallel")]
pub mod parallel;
mod plumbing;
#[cfg(test)]
mod testmocks;
use std::fmt;
use std::fmt::Debug;
use std::hash as std_hash;
use std::iter::{DoubleEndedIterator, ExactSizeIterator, Iterator};
use std::slice;
#[derive(Debug)]
#[cfg_attr(feature = "serialization", derive(Serialize))]
pub struct MerkleTree<H, T> {
root: Node<H, T>,
}
#[cfg_attr(feature = "serialization", derive(Serialize))]
pub enum Node<H, T> {
Leaf(LeafNode<H, T>),
Hash(HashNode<H, T>),
}
#[derive(Debug)]
#[cfg_attr(feature = "serialization", derive(Serialize))]
pub struct LeafNode<H, T> {
hash: H,
data: T,
}
#[derive(Debug)]
#[cfg_attr(feature = "serialization", derive(Serialize))]
pub struct HashNode<H, T> {
hash: H,
children: Box<[Node<H, T>]>,
}
impl<H, T> MerkleTree<H, T> {
pub fn root(&self) -> &Node<H, T> {
&self.root
}
}
impl<H: Debug, T: Debug> Debug for Node<H, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Node::Leaf(ref ln) => ln.fmt(f),
Node::Hash(ref hn) => hn.fmt(f),
}
}
}
impl<H, T> Node<H, T> {
pub fn hash(&self) -> &H {
match *self {
Node::Leaf(ref ln) => &ln.hash,
Node::Hash(ref hn) => &hn.hash,
}
}
}
impl<H: AsRef<[u8]>, T> Node<H, T> {
pub fn hash_bytes(&self) -> &[u8] {
self.hash().as_ref()
}
}
impl<H: AsRef<[u8]>, T> LeafNode<H, T> {
pub fn hash_bytes(&self) -> &[u8] {
self.hash.as_ref()
}
}
impl<H, T> LeafNode<H, T> {
pub fn hash(&self) -> &H {
&self.hash
}
pub fn data(&self) -> &T {
&self.data
}
}
impl<H: AsRef<[u8]>, T> HashNode<H, T> {
pub fn hash_bytes(&self) -> &[u8] {
self.hash.as_ref()
}
}
impl<H, T> HashNode<H, T> {
pub fn hash(&self) -> &H {
&self.hash
}
pub fn child_at(&self, index: usize) -> &Node<H, T> {
&self.children[index]
}
pub fn children<'a>(&'a self) -> Children<'a, H, T> {
Children(self.children.iter())
}
}
macro_rules! impl_eq_for {
($($Name:ident),+) => {
$(impl<H: Eq, T> Eq for $Name<H, T> {})+
}
}
macro_rules! impl_partial_eq {
{
$(
<$Rhs:ident> for $This:ident: (&$self:ident, &$other:ident) {
$logic:expr
}
)+
} => {
$(
impl<H: PartialEq, T> PartialEq<$Rhs<H, T>> for $This<H, T> {
fn eq(&$self, $other: &$Rhs<H, T>) -> bool {
$logic
}
}
)+
}
}
macro_rules! impl_hash_for {
{
$(
$This:ident: (&$self:ident) {
$get_hash:expr
}
)+
} => {
$(
impl<H: std_hash::Hash, T> std_hash::Hash for $This<H, T> {
fn hash<S: std_hash::Hasher>(&$self, state: &mut S) {
$get_hash.hash(state)
}
}
)+
}
}
impl_eq_for!(MerkleTree, Node, LeafNode, HashNode);
impl_partial_eq! {
<MerkleTree> for MerkleTree: (&self, &other) {
self.root() == other.root()
}
<Node> for MerkleTree: (&self, &other) {
self.root() == other
}
<LeafNode> for MerkleTree: (&self, &other) {
self.root() == other
}
<HashNode> for MerkleTree: (&self, &other) {
self.root() == other
}
<MerkleTree> for Node: (&self, &other) {
self == other.root()
}
<Node> for Node: (&self, &other) {
match (self, other) {
(&Node::Leaf(ref lhs), &Node::Leaf(ref rhs)) => lhs == rhs,
(&Node::Hash(ref lhs), &Node::Hash(ref rhs)) => lhs == rhs,
_ => false
}
}
<LeafNode> for Node: (&self, &other) {
match *self {
Node::Leaf(ref lhs) => lhs == other,
_ => false
}
}
<HashNode> for Node: (&self, &other) {
match *self {
Node::Hash(ref lhs) => lhs == other,
_ => false
}
}
<MerkleTree> for LeafNode: (&self, &other) {
self == other.root()
}
<Node> for LeafNode: (&self, &other) {
match *other {
Node::Leaf(ref rhs) => self == rhs,
_ => false
}
}
<LeafNode> for LeafNode: (&self, &other) {
self.hash() == other.hash()
}
<MerkleTree> for HashNode: (&self, &other) {
self == other.root()
}
<Node> for HashNode: (&self, &other) {
match *other {
Node::Hash(ref rhs) => self == rhs,
_ => false
}
}
<HashNode> for HashNode: (&self, &other) {
self.hash() == other.hash()
}
}
impl_hash_for! {
MerkleTree: (&self) {
self.root().hash()
}
Node: (&self) {
self.hash()
}
LeafNode: (&self) {
self.hash()
}
HashNode: (&self) {
self.hash()
}
}
#[derive(Debug)]
pub struct Children<'a, H: 'a, T: 'a>(slice::Iter<'a, Node<H, T>>);
impl<'a, H, T> Clone for Children<'a, H, T> {
fn clone(&self) -> Self {
Children(self.0.clone())
}
}
impl<'a, H, T> Iterator for Children<'a, H, T> {
type Item = &'a Node<H, T>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> usize {
self.0.count()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth(n)
}
fn last(self) -> Option<Self::Item> {
self.0.last()
}
}
impl<'a, H, T> ExactSizeIterator for Children<'a, H, T> {
fn len(&self) -> usize {
self.0.len()
}
}
impl<'a, H, T> DoubleEndedIterator for Children<'a, H, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}