vsdb 17.0.15

A std-collection-like database
use crate::trie::{
    error::Result,
    nibbles::Nibbles,
    node::{Node, NodeHandle},
};

pub struct TrieRo<'a> {
    root: &'a NodeHandle,
}

impl<'a> TrieRo<'a> {
    pub fn new(root: &'a NodeHandle) -> Self {
        Self { root }
    }

    pub fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
        if matches!(self.root, NodeHandle::InMemory(n) if **n == Node::Null) {
            return Ok(None);
        }

        let path = Nibbles::from_raw(key);
        let mut remaining = path.as_slice();
        let mut node = self.root.node();
        loop {
            match node {
                Node::Null => return Ok(None),
                Node::Leaf {
                    path: leaf_path,
                    value,
                } => {
                    return Ok(
                        (leaf_path.as_slice() == remaining).then(|| value.clone())
                    );
                }
                Node::Extension {
                    path: ext_path,
                    child,
                } => {
                    let Some(rest) = remaining.strip_prefix(ext_path.as_slice()) else {
                        return Ok(None);
                    };
                    remaining = rest;
                    node = child.node();
                }
                Node::Branch { children, value } => {
                    let Some((&index, rest)) = remaining.split_first() else {
                        return Ok(value.clone());
                    };
                    let Some(child) = &children[index as usize] else {
                        return Ok(None);
                    };
                    remaining = rest;
                    node = child.node();
                }
            }
        }
    }
}