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());
}