use devicons::{icon_for_file, File, Theme};
use std::fs;
use std::path::Path;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
const DIRECTORY_ICON: char = '';
const TREE_BRANCH: &str = "├── ";
const TREE_LAST_BRANCH: &str = "└── ";
pub fn handle_directory(path: &Path) -> std::io::Result<()> {
print_root_directory(path)?;
print_directory_contents(path)?;
Ok(())
}
fn print_root_directory(dir: &Path) -> std::io::Result<()> {
let mut stdout = StandardStream::stdout(ColorChoice::Always);
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Blue)).set_bold(true))?;
println!("{} {}", DIRECTORY_ICON, dir.display());
stdout.reset()?;
Ok(())
}
fn print_directory_contents(dir: &Path) -> std::io::Result<()> {
let mut stdout = StandardStream::stdout(ColorChoice::Always);
if dir.is_dir() {
let mut entries: Vec<_> = fs::read_dir(dir)?.collect::<Result<_, _>>()?;
entries.sort_by_key(|entry| {
let path = entry.path();
(
!path.is_dir(),
path.file_name()
.unwrap_or_default()
.to_string_lossy()
.to_string(),
)
});
for (index, entry) in entries.iter().enumerate() {
let path = entry.path();
let is_last = index == entries.len() - 1;
if is_last {
print!("{}", TREE_LAST_BRANCH);
} else {
print!("{}", TREE_BRANCH);
}
if path.is_dir() {
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Blue)).set_bold(true))?;
println!(
"{} {}",
DIRECTORY_ICON,
path.file_name().unwrap().to_string_lossy()
);
stdout.reset()?;
} else {
let file = File::new(&path);
let icon = icon_for_file(&file, Some(Theme::Dark));
stdout.set_color(ColorSpec::new().set_fg(Some(Color::White)))?;
println!(
"{} {}",
icon.icon,
path.file_name().unwrap().to_string_lossy()
);
stdout.reset()?;
}
}
}
Ok(())
}