bawa 0.1.0

A TUI game save organizer
Documentation
use super::item::TreeItem;
use crate::tree::{
    traverse::{Edge, Traverse},
    NodeId,
};
use ratatui::{style::Style, widgets::Block};
use std::fmt::Display;

#[derive(Default)]
pub struct Tree<'a> {
    pub block: Option<Block<'a>>,
    pub items: Vec<TreeItem<'a>>,
    pub style: Style,
    pub highlight_style: Style,
    pub marked_style: Style,
    pub active_style: Style,
}

impl<'a> Tree<'a> {
    pub fn new<T>(items: T) -> Self
    where
        T: IntoIterator<Item: Into<TreeItem<'a>>>,
    {
        Self {
            items: items.into_iter().map(Into::into).collect(),
            ..Self::default()
        }
    }

    pub fn block(mut self, block: Block<'a>) -> Self {
        self.block = Some(block);
        self
    }

    pub fn highlight_style(mut self, style: Style) -> Self {
        self.highlight_style = style;
        self
    }

    pub fn marked_style(mut self, style: Style) -> Self {
        self.marked_style = style;
        self
    }

    pub fn active_style(mut self, style: Style) -> Self {
        self.active_style = style;
        self
    }
}

impl<T> From<&crate::tree::Tree<T>> for Tree<'_>
where
    T: Display,
{
    fn from(tree: &crate::tree::Tree<T>) -> Self {
        let mut items = Vec::new();
        let mut depth = 0;

        for edge in Traverse::new(NodeId::root(), tree).visible().skip(1) {
            match edge {
                Edge::Start(id) => {
                    let node = &tree[id];
                    let last_item =
                        depth != 0 && node.next_sibling.is_none() && !node.has_children();
                    items.push(TreeItem::new(id, depth, last_item, tree));
                    depth += 1;
                }
                Edge::End(_) => depth -= 1,
            }
        }

        Tree::new(items)
    }
}