display-node 0.1.0

Tiny crate adding a trait to display recursive structures like node trees.
Documentation
use std::{
    fmt::Display,
    slice::{Iter, IterMut},
};

use crate::DisplayableNode;

pub struct Tree<D> {
    data: D,
    children: Vec<Tree<D>>,
}

impl<D> Tree<D> {
    pub fn new(data: D) -> Self {
        Self {
            data,
            children: vec![],
        }
    }

    pub fn assemble(data: D, children: Vec<Self>) -> Self {
        Self { data, children }
    }

    pub fn data_ref(&self) -> &D {
        &self.data
    }

    pub fn data_mut(&mut self) -> &mut D {
        &mut self.data
    }

    pub fn push(&mut self, data: Tree<D>) {
        self.children.push(data)
    }

    pub fn pull(&mut self) -> Option<Tree<D>> {
        if self.children.is_empty() {
            return None;
        }
        let last_index = self.children.len() - 1;
        let child = self.children.remove(last_index);
        Some(child)
    }

    pub fn get_child(&self, index: usize) -> Option<&Tree<D>> {
        self.children.get(index)
    }

    pub fn get_child_mut(&mut self, index: usize) -> Option<&mut Tree<D>> {
        self.children.get_mut(index)
    }

    pub fn children_ref(&self) -> Iter<'_, Tree<D>> {
        self.children.iter()
    }

    pub fn children_mut(&mut self) -> IterMut<'_, Tree<D>> {
        self.children.iter_mut()
    }

    pub fn insert(&mut self, _index: usize) {
        todo!()
    }

    pub fn take(&mut self, _index: usize) {
        todo!()
    }
}

impl<D: Display> DisplayableNode for Tree<D> {
    fn label(&self) -> Option<String> {
        let data = &self.data;
        Some(format!("{data}"))
    }

    fn children(&self) -> Vec<&Self> {
        self.children_ref().collect()
    }
}

#[macro_export]
macro_rules! tree {
    ($value:expr, $children:expr) => {{
        Tree::assemble($value, $children)
    }};
    ($value:expr) => {{
        Tree::new($value)
    }};
}

#[test]
fn it_works() {
    let tree = tree!(
        "root",
        vec![
            tree!(
                "folder-1",
                vec![
                    tree!("file-1-1"),
                    tree!("file-1-2"),
                    tree!("file-1-3"),
                    tree!("file-1-4")
                ]
            ),
            tree!(
                "folder-2",
                vec![
                    tree!(
                        "folder-2-1",
                        vec![tree!("file-2-1-1"), tree!("file-2-1-2"),]
                    ),
                    tree!("file-2-1"),
                    tree!("file-2-2"),
                ]
            )
        ]
    );
    println!("{}", tree.display());
}