clide/src/tui/explorer.rs

84 lines
2.6 KiB
Rust
Raw Normal View History

2026-01-19 09:23:12 -05:00
use crate::tui::component::Component;
2026-01-17 17:09:42 -05:00
use anyhow::Result;
use ratatui::buffer::Buffer;
2026-01-17 17:39:13 -05:00
use ratatui::layout::{Alignment, Rect};
use ratatui::prelude::Style;
2026-01-17 17:39:13 -05:00
use ratatui::style::Color;
use ratatui::widgets::{Block, Borders, Widget};
2026-01-17 17:09:42 -05:00
use std::fs;
use tui_tree_widget::{Tree, TreeItem};
use uuid::Uuid;
2026-01-17 17:09:42 -05:00
#[derive(Clone, Debug)]
pub struct Explorer<'a> {
2026-01-19 09:23:12 -05:00
root_path: std::path::PathBuf,
2026-01-17 17:09:42 -05:00
tree_items: TreeItem<'a, String>,
}
impl<'a> Explorer<'a> {
2026-01-19 09:23:12 -05:00
pub fn new(path: std::path::PathBuf) -> Self {
let explorer = Explorer {
2026-01-19 09:23:12 -05:00
root_path: path.to_owned(),
tree_items: Self::build_tree_from_path(path),
2026-01-17 17:09:42 -05:00
};
explorer
}
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::<Result<Vec<_>, 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(),
2026-01-19 09:23:12 -05:00
path.file_name()
.expect("Failed to get file name from path.")
.to_string_lossy()
.to_string(),
));
}
}
}
TreeItem::new(
Uuid::new_v4().to_string(),
path.file_name()
2026-01-19 09:23:12 -05:00
.expect("Failed to get file name from path.")
.to_string_lossy()
.to_string(),
children,
)
2026-01-17 17:09:42 -05:00
.expect("Failed to build tree from path.")
}
}
2026-01-17 17:09:42 -05:00
impl<'a> Widget for &Explorer<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
Tree::new(&self.tree_items.children())
.expect("Failed to build tree.")
.style(Style::default())
2026-01-17 17:39:13 -05:00
.block(
Block::default()
.borders(Borders::ALL)
.title(
self.root_path
.file_name()
.expect("Failed to get file name from path.")
.to_string_lossy(),
)
.title_style(Style::default().fg(Color::Green))
.title_alignment(Alignment::Center),
)
2026-01-17 17:09:42 -05:00
.render(area, buf);
}
}
2026-01-19 09:23:12 -05:00
impl<'a> Component for Explorer<'a> {}