use std::fs; use ratatui::buffer::Buffer; use ratatui::layout::Rect; use ratatui::prelude::Style; use ratatui::widgets::{Block, Borders, Widget}; use tui_tree_widget::{Tree, TreeItem}; use uuid::Uuid; #[derive(Clone, Copy, Debug)] pub struct Explorer<'a> { root_path: &'a std::path::Path, } impl<'a> Explorer<'a> { pub fn new(path: &'a std::path::Path) -> Self { Explorer { root_path: path } } pub fn draw(self, area: Rect, buf: &mut Buffer) { let tree_item = Self::build_tree_from_path(self.root_path.to_path_buf()); Tree::new(&tree_item.children()) .expect("Failed to build tree.") .style(Style::default()) .block(Block::default().borders(Borders::ALL)) .render(area, buf); } fn build_tree_from_path(path: std::path::PathBuf) -> TreeItem<'static, String> { let mut children = vec![]; if let Ok(entries) = fs::read_dir(&path) { let mut paths = entries .map(|res| res.map(|e| e.path())) .collect::, std::io::Error>>() .expect(""); paths.sort(); for path in paths { if path.is_dir() { children.push(Self::build_tree_from_path(path)); } else { children.push(TreeItem::new_leaf( Uuid::new_v4().to_string(), path.file_name().unwrap().to_string_lossy().to_string(), )); } } } TreeItem::new( Uuid::new_v4().to_string(), path.file_name() .unwrap_or_default() .to_string_lossy() .to_string(), children, ) .expect("Failed to build tree from path.") } }