use fs_extra::{dir, file}; use std::env; use std::fs::OpenOptions; use std::path::PathBuf; // TODO: Configuration options in programs config file: // - Always permanently delete files, // - Handle naming collisions by changing file name instead of erroring, // - Set .trash path. // TODO: Option to permanently delete file. // TODO: .trash path option. fn main() -> anyhow::Result<()> { let ret = clparse::Arguments::parse_from_args()?; let args = ret.1; let trash_path = env::var("HOME")? + "/.trash/"; let from = PathBuf::from({ let p = args.arguments.get("p"); let path = args.arguments.get("path"); match (p, path) { (None, None) => anyhow::bail!("No path specified"), (None, Some(path)) => path, (Some(path), None) => path, (Some(_), Some(_)) => anyhow::bail!("Option p and path conflict"), } }) .canonicalize()?; let name = from .file_name() .map(|name| name.to_str()) .flatten() .ok_or(anyhow::anyhow!("Weird file name"))?; let manifest = trash_manifest::Manifest::new( OpenOptions::new() .create(true) .write(true) .read(true) .open(trash_path.clone() + ".manifest.ron")?, )?; let is_in_trash = if from.to_string_lossy() == trash_path.clone() + name { true } else { false }; match ( is_in_trash, args.arguments.get("dir").is_some() || args.arguments.get("d").is_some(), ) { (true, true) => fs_extra::dir::remove(from.clone())?, (true, false) => fs_extra::file::remove(from.clone())?, (false, true) => { fs_extra::dir::move_dir(from.clone(), trash_path + name, &dir::CopyOptions::new())?; } (false, false) => { fs_extra::file::move_file(from.clone(), trash_path + name, &file::CopyOptions::new())?; } } if !is_in_trash { manifest.add(name.to_string(), from.clone())?; } Ok(()) }