use graphex::*;
use std::path::PathBuf;
struct Directory(pub PathBuf);
fn conv(err: std::io::Error) -> graphex::Error {
graphex::Error::Other(Box::new(err))
}
impl Node for Directory {
fn sep(&self) -> &str {
"/"
}
fn next(&self, key: &str) -> ExploreResult {
let mut child_path = self.0.clone();
child_path.push(key);
if child_path.is_dir() {
Ok(Box::new(Directory(child_path)).into())
} else if child_path.is_file() {
Ok(Box::new(File(child_path)).into())
} else if child_path.is_symlink() {
Ok(Box::new(Link(child_path)).into())
} else {
Err(Error::key(key))
}
}
fn display(&self) -> &dyn Display {
self
}
}
impl graphex::Display for Directory {
fn header_footer(&self) -> Option<(String, String)> {
let header = self
.0
.file_name()
.unwrap_or_else(|| self.0.as_os_str())
.to_string_lossy()
.to_string();
Some((header, String::new()))
}
fn print_content(&self, out: &mut graphex::Output) -> Result {
for entry in self.0.read_dir().map_err(conv)? {
let entry = entry.map_err(conv)?;
let file_type = entry.file_type().map_err(conv)?;
let type_str = if file_type.is_dir() {
"Dir"
} else if file_type.is_file() {
"File"
} else if file_type.is_symlink() {
"SymLink"
} else {
"Unknown"
};
out.item(&entry.file_name().to_string_lossy(), &type_str)?
}
Ok(())
}
}
struct File(pub PathBuf);
impl Node for File {
fn next(&self, key: &str) -> ExploreResult {
Err(Error::key(key))
}
fn display(&self) -> &dyn Display {
self
}
}
impl graphex::Display for File {
fn print_content(&self, out: &mut Output) -> Result {
let content = std::fs::read_to_string(&self.0).map_err(conv)?;
out.write_str(&content)
}
}
struct Link(pub PathBuf);
impl Node for Link {
fn next(&self, key: &str) -> ExploreResult {
Err(Error::key(key))
}
fn display(&self) -> &dyn Display {
self
}
}
impl graphex::Display for Link {
fn print_content(&self, out: &mut Output) -> Result {
let target = self.0.read_link().map_err(conv)?;
write!(out, "{}", target.display())
}
}
struct Cli {
path: PathBuf,
key: String,
}
fn parse_cmd() -> Cli {
let path = std::env::args().nth(1).expect("no root path given");
let key = std::env::args().nth(2).expect("no key given");
Cli {
path: std::path::PathBuf::from(path),
key,
}
}
fn main() {
let cli = parse_cmd();
let root = Directory(cli.path.clone());
println!("{}", graphex::explore_to_string(&root, &cli.key).unwrap());
}