ableos_userland/programs/delete/src/main.rs

67 lines
2.0 KiB
Rust

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(())
}