ethereum-trie 0.5.0

Lightweight Ethereum world state storage.
Documentation
use merkle::{MerkleValue, MerkleNode};
use merkle::nibble::NibbleVec;
use {DatabaseHandle, Error};

use rlp::Rlp;

pub fn get_by_value<'a, D: DatabaseHandle>(
    merkle: MerkleValue<'a>, nibble: NibbleVec, database: &'a D
) -> Result<Option<&'a [u8]>, Error> {
    match merkle {
        MerkleValue::Empty => Ok(None),
        MerkleValue::Full(subnode) => {
            get_by_node(subnode.as_ref().clone(), nibble, database)
        },
        MerkleValue::Hash(h) => {
            let subnode = MerkleNode::decode(&Rlp::new(database.get_with_error(h)?));
            get_by_node(subnode, nibble, database)
        },
    }
}

pub fn get_by_node<'a, D: DatabaseHandle>(
    node: MerkleNode<'a>, nibble: NibbleVec, database: &'a D
) -> Result<Option<&'a [u8]>, Error> {
    match node {
        MerkleNode::Leaf(node_nibble, node_value) => {
            if node_nibble == nibble {
                Ok(Some(node_value))
            } else {
                Ok(None)
            }
        },
        MerkleNode::Extension(node_nibble, node_value) => {
            if nibble.starts_with(&node_nibble) {
                get_by_value(node_value, nibble[node_nibble.len()..].into(), database)
            } else {
                Ok(None)
            }
        },
        MerkleNode::Branch(node_nodes, node_additional) => {
            if nibble.len() == 0 {
                Ok(node_additional)
            } else {
                let ni: usize = nibble[0].into();
                get_by_value(node_nodes[ni].clone(), nibble[1..].into(), database)
            }
        },
    }
}