byte_trie 0.3.0

A compressed trie based on bytes with some weird child node bucket sizes.
Documentation
use crate::child::Child;
use crate::keys::BytesKey;
use crate::nodes::AdaptiveNode;
use crate::tries::{BitTrie, ByteTrie, NibbleTrie};
use serde::ser::SerializeMap;
use serde::{Serialize, Serializer};

impl<T> Serialize for ByteTrie<T>
where
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_newtype_struct("ByteTrie", &self.root)
    }
}

impl<T> Serialize for NibbleTrie<T>
where
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_newtype_struct("NibbleTrie", &self.root)
    }
}

impl<T> Serialize for BitTrie<T>
where
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_newtype_struct("BitTrie", &self.root)
    }
}

impl<K, T> Serialize for AdaptiveNode<K, T>
where
    K: BytesKey,
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(None)?;

        flatten_node(&self)
            .iter()
            .try_for_each(|n| node_or_children(n, &mut map))?;

        map.end()
    }
}

fn node_or_children<K, T, M>(node: &AdaptiveNode<K, T>, map: &mut M) -> Result<(), M::Error>
where
    K: BytesKey,
    T: Serialize,
    M: SerializeMap,
{
    let is_empty = match &node.child {
        Some(child) => child.is_empty(),
        None => true,
    };

    if is_empty {
        map.serialize_entry(&node.key.to_string(), &node.value)
    } else {
        map.serialize_entry(&node.key.to_string(), &node.child)
    }
}

fn flatten_node<K, T>(node: &AdaptiveNode<K, T>) -> Vec<&AdaptiveNode<K, T>>
where
    K: BytesKey,
    T: Serialize,
{
    if !node.key.get().is_empty() {
        return vec![node];
    }

    match &node.child {
        Some(child) => child.child().iter().fold(Vec::new(), |mut acc, child| {
            if let Some(child) = child {
                acc.append(&mut flatten_node(child));
            }

            acc
        }),
        None => Vec::new(),
    }
}

impl<K, T> Serialize for Child<K, T>
where
    K: BytesKey,
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(None)?;

        self.child()
            .iter()
            .filter_map(|c| c.as_ref().map(flatten_node))
            .try_for_each(|nodes| {
                nodes
                    .iter()
                    .try_for_each(|node| node_or_children(node, &mut map))
            })?;

        map.end()
    }
}