nb-tree 0.2.0-alpha01

Very simple tree structure with generic node and branch data.
Documentation
use std::{
    hash::Hash,
    ops::{Deref, DerefMut},
};

use crate::{
    path::Path,
    prelude::iter::depth::{Iter, TreeIterTarget},
    tree::{
        position::{AttachedPosition, DetachedPosition},
        Position,
    },
};

use super::{detached::DetachedEntry, Entry, NodeIDX, Tree, NODEBOUND, TREEBOUND};

pub type TreeNode<R, N, B> = Node<R, N, B, NODEBOUND>;

pub struct Node<R, N, B, const BOUND: bool>
where
    R: Deref<Target = Tree<N, B>>,
{
    pub(super) tree: R,
    pub(super) position: AttachedPosition<B, NodeIDX>,
}

impl<R, N, B, const BOUND: bool> Deref for Node<R, N, B, BOUND>
where
    R: Deref<Target = Tree<N, B>>,
{
    type Target = N;

    fn deref(&self) -> &Self::Target {
        self.value()
    }
}

impl<R, N, B, const BOUND: bool> DerefMut for Node<R, N, B, BOUND>
where
    R: DerefMut<Target = Tree<N, B>>,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.value_mut()
    }
}

impl<R, N, B, const BOUND: bool> From<(R, Path<B>, Path<NodeIDX>)> for Node<R, N, B, BOUND>
where
    R: Deref<Target = Tree<N, B>>,
{
    fn from((tree, path, idxs): (R, Path<B>, Path<NodeIDX>)) -> Self {
        Self {
            tree,
            position: AttachedPosition::from(path, idxs),
        }
    }
}

impl<R, N, B, const BOUND: bool> Node<R, N, B, BOUND>
where
    R: Deref<Target = Tree<N, B>>,
{
    pub fn from(tree: R, position: AttachedPosition<B, NodeIDX>) -> Self {
        Self { tree, position }
    }

    pub(super) fn into_detached_entry(
        self,
        position: DetachedPosition<B, NodeIDX>,
    ) -> DetachedEntry<R, N, B, BOUND> {
        DetachedEntry {
            tree: self.tree,
            position,
        }
    }

    pub fn into_entry(self) -> Entry<R, N, B, BOUND> {
        self.into()
    }

    pub fn branch(&self) -> Option<&B> {
        self.position.at_branch()
    }

    pub fn children(&self) -> Vec<&B> {
        self.tree.nodes[*self.position.at()]
            .children
            .keys()
            .collect() //_vec()
    }

    pub fn path(&self) -> &Path<B> {
        self.position.path()
    }

    pub fn value(&self) -> &N {
        &self.tree.nodes[*self.position.at()].value
    }
}

impl<R, N, B, const BOUND: bool> Node<R, N, B, BOUND>
where
    R: DerefMut<Target = Tree<N, B>>,
{
    pub fn insert(&mut self, value: N) -> N {
        std::mem::replace(&mut self.tree.nodes[*self.position.at()].value, value)
    }

    pub fn value_mut(&mut self) -> &mut N {
        &mut self.tree.nodes[*self.position.at()].value
    }
}

impl<'a, N, B> Node<&'a Tree<N, B>, N, B, TREEBOUND> {
    pub fn iter<T: TreeIterTarget<'a, N, B>>(&self) -> Iter<'a, N, B, T> {
        Iter::new(self.tree)
    }
}
// TODO: iter_mut()

impl<R, N, B> Node<R, N, B, TREEBOUND>
where
    R: Deref<Target = Tree<N, B>>,
{
    pub fn move_up(&mut self, up: usize) -> Option<usize> {
        self.position.move_up(up)
    }
}

impl<R, N, B> Node<R, N, B, TREEBOUND>
where
    R: Deref<Target = Tree<N, B>>,
    B: Eq + Hash,
{
    pub fn move_down(mut self, mut path: Path<B>) -> Entry<R, N, B, TREEBOUND> {
        let mut position = Position::Attached(self.position);
        let mut p_idx = *position.attached_mut().unwrap().at();
        while position.is_attached() {
            if path.is_empty() {
                break;
            }
            let branch = path.pop_first().unwrap();
            match self.tree.nodes[p_idx].children.get(&branch).copied() {
                Some(idx) => {
                    position.attached_mut().unwrap().move_down(branch, idx);
                    p_idx = idx;
                }
                None => {
                    let detached = match position {
                        Position::Attached(attached) => attached.move_down_detach(branch),
                        Position::Detached(detached) => detached,
                    };
                    position = Position::Detached(detached);
                }
            }
        }
        if let Position::Detached(mut detached_position) = position {
            for branch in path {
                detached_position.move_down(branch);
            }
            DetachedEntry::from(self.tree, detached_position).into()
        } else {
            self.position = position.unwrap_attached();
            self.into()
        }
    }

    pub fn move_down_branch(mut self, branch: B) -> Entry<R, N, B, TREEBOUND> {
        if let Some(idx) = self.tree.nodes[*self.position.at()]
            .children
            .get(&branch)
            .copied()
        {
            self.position.move_down(branch, idx);
            self.into()
        } else {
            DetachedEntry::from(self.tree, self.position.move_down_detach(branch)).into()
        }
    }
}
impl<R, N, B> Node<R, N, B, TREEBOUND>
where
    R: DerefMut<Target = Tree<N, B>>,
    B: Eq + Hash + Clone,
{
    pub fn remove_subtree(mut self) -> DetachedEntry<R, N, B, TREEBOUND> {
        if let Some((_, &p_idx)) = self.position.parent() {
            self.tree
                .remove_subtree_at(p_idx, self.position.at_branch().unwrap().clone());
        } else {
            // Root node
            self.tree.clear();
        }
        DetachedEntry::from(self.tree, self.position.remove_node())
    }

    pub fn remove_child_subtrees(&mut self, children: Vec<B>) {
        for c in children {
            self.tree.remove_subtree_at(*self.position.at(), c);
        }
    }
}

//TODO
/*
impl<R, N, B> Node<R, N, B>
where
    R: Deref<Target = Tree<N, B>>,
    N: Eq,
    B: Eq + Hash,
{
    pub fn subtree_eq(&self) -> bool {}
}
*/