reindeer 0.1.3

A small entity-based embedded database with a minimal no-SQL relationnal model, written in pure Rust.
Documentation
use hashers::fx_hash::FxHasher;
use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
use std::hash::BuildHasherDefault;

use crate::entity::AsBytes;
use crate::Entity;

use super::DeletionBehaviour;

#[doc(hidden)]
pub type RelationMap =
    HashMap<String, Vec<(Vec<u8>, DeletionBehaviour)>, BuildHasherDefault<FxHasher>>;

#[doc(hidden)]
#[derive(Serialize, Deserialize, Default)]
pub struct RelationDescriptor {
    pub related_entities: RelationMap,
}

#[doc(hidden)]
#[derive(Serialize, Deserialize, Default)]
pub struct FamilyDescriptor {
    pub tree_name: String,
    pub sibling_trees: Vec<(String, DeletionBehaviour)>,
    pub child_trees: Vec<(String, DeletionBehaviour)>,
}

#[doc(hidden)]
impl RelationDescriptor {
    pub fn add_related<E: Entity>(&mut self, e: &E, behaviour: DeletionBehaviour) {
        let key = e.get_key().as_bytes();
        self.add_related_by_key(E::store_name(), &key, behaviour);
    }

    pub fn add_related_by_key(
        &mut self,
        tree_name: &str,
        key: &[u8],
        behaviour: DeletionBehaviour,
    ) {
        if let Some(v) = self.related_entities.get_mut(tree_name) {
            v.push((key.to_vec(), behaviour))
        } else {
            self.related_entities
                .insert(String::from(tree_name), vec![(key.to_vec(), behaviour)]);
        }
    }

    pub fn remove_related_by_key<E: Entity>(&mut self, e: &[u8]) {
        self.remove_related_by_key_and_tree_name(E::store_name(), e)
    }

    pub fn remove_related_by_key_and_tree_name(&mut self, tree: &str, e: &[u8]) {
        if let Some(v) = self.related_entities.get_mut(tree) {
            if let Some(index) = v
                .iter()
                .position(|(value, _)| value.to_ascii_lowercase() == e.to_ascii_lowercase())
            {
                v.remove(index);
            }
        }
    }
}

#[doc(hidden)]
impl Entity for FamilyDescriptor {
    type Key = String;

    fn store_name() -> &'static str {
        "__$family_rel"
    }

    fn get_key(&self) -> &Self::Key {
        &self.tree_name
    }

    fn set_key(&mut self, key: &Self::Key) {
        self.tree_name = key.clone();
    }
}