strune 0.1.2

A simple, directional knowledge structure library for building linked references and word books
Documentation
use std::collections::HashMap;
use crate::core::Node;

pub trait MaybeDependents {
    fn dependents(&self) -> Option<&[String]>;
    fn dependents_mut(&mut self) -> &mut Option<Vec<String>>;
}

pub trait HasDependents {
    fn dependents(&self) -> &[String];
    fn dependents_mut(&mut self) -> &mut Vec<String>;
}

#[macro_export]
macro_rules! impl_has_dependents_detail {
    (<$($gen:tt),*> $ty:ty, $field:ident) => {
        $crate::impl_has!(
            <$($gen),*> $ty, $field;
            $crate::operation::HasDependents,
            dependents -> &[String],
            dependents_mut -> &mut Vec<String>
        );
    };
}

#[macro_export]
macro_rules! impl_has_dependents {
    ($name:ident) => {
        $crate::impl_has_dependents_detail!(<T> $name<T>, dependents);
    };
}

#[macro_export]
macro_rules! impl_maybe_dependents_detail {
    (<$($gen:tt),*> $ty:ty, $field:ident) => {
        $crate::impl_maybe!(
            <$($gen),*> $ty, $field;
            $crate::operation::MaybeDependents,
            dependents -> Option<&[String]>,
            dependents_mut -> &mut Option<Vec<String>>
        );
    };
}


#[macro_export]
macro_rules! impl_maybe_dependents {
    ($name:ident) => {
        $crate::impl_maybe_dependents_detail!(<T> $name<T>, dependents);
    };
}

pub fn fill_dependents<T>(mut nodes: Vec<Node<T>>) -> Vec<Node<T>>
where
    T: MaybeDependents,
{
    let mut reverse: HashMap<String, Vec<String>> = HashMap::new();

    for node in &nodes {
        for dep in &node.dependencies {
            reverse.entry(dep.clone()).or_default().push(node.label.clone());
        }
    }

    for node in &mut nodes {
        let deps = reverse.remove(&node.label).unwrap_or_default();
        let slot = node.options.dependents_mut();
        *slot = Some(deps);
    }

    nodes
}