Exit status now depends on Result

This commit is contained in:
Michael Zhang 2021-12-30 21:57:26 -06:00
parent b8d2be4abe
commit 53041af73c
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
5 changed files with 59 additions and 7 deletions

View file

@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::{fmt, iter, path::PathBuf};
/// Result convenience type for the Error type
pub type Result<T, E = Error> = std::result::Result<T, E>;
@ -10,6 +10,9 @@ pub enum Error {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Path doesn't exist: {0}")]
FileDoesntExist(PathBuf),
#[error("Could not open file {0:?}: {1}")]
OpenFile(PathBuf, std::io::Error),
@ -36,6 +39,44 @@ pub enum Error {
#[error("Put error: {0}")]
Put(#[from] crate::ops::put::PutError),
#[error("{0} and {1}")]
And(Box<Error>, Box<Error>),
#[error("{0}")]
Multiple(MultipleErrors),
}
impl Error {
/// Construct an error consisting of multiple errors
pub fn multiple(errors: impl Iterator<Item = Error>) -> Self {
Error::Multiple(MultipleErrors(
errors
.map(|err| -> Box<dyn Iterator<Item = Error>> {
match err {
Error::Multiple(MultipleErrors(errors)) => {
Box::new(errors.into_iter())
}
_ => Box::new(iter::once(err)),
}
})
.flatten()
.collect(),
))
}
}
#[derive(Debug)]
pub struct MultipleErrors(Vec<Error>);
impl fmt::Display for MultipleErrors {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "")?;
for err in self.0.iter() {
writeln!(f, "- {}", err)?;
}
Ok(())
}
}
/// Errors related to .trashinfo files

View file

@ -1,5 +1,10 @@
#![deny(warnings)]
#[macro_use]
extern crate log;
use std::process::exit;
use garbage::{
ops::{self, EmptyOptions, ListOptions, PutOptions, RestoreOptions},
Result,
@ -61,7 +66,8 @@ fn main() {
match run(opt.command) {
Ok(_) => (),
Err(err) => {
eprintln!("Error: {}", err);
error!("{}", err);
exit(1);
}
}
}

View file

@ -4,8 +4,8 @@ use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use libmount::mountinfo::Parser;
use libc::c_ulong;
use libmount::mountinfo::Parser;
use crate::errors::Error;
use crate::utils;

View file

@ -65,11 +65,13 @@ pub struct PutOptions {
/// Throw some files into the trash.
pub fn put(options: PutOptions) -> Result<()> {
let mut errors = vec![];
for path in options.paths.iter() {
let abs_path = utils::into_absolute(&path)?;
if !abs_path.exists() {
error!("Skipping non-existent path {:?}", path);
errors.push(Error::FileDoesntExist(path.clone()));
continue;
}
@ -102,7 +104,11 @@ pub fn put(options: PutOptions) -> Result<()> {
}
}
Ok(())
if errors.is_empty() {
Ok(())
} else {
Err(Error::multiple(errors.into_iter()))
}
}
/// DeletionStrategy describes a strategy by which a file is deleted

View file

@ -24,8 +24,7 @@ pub fn into_absolute(path: impl AsRef<Path>) -> Result<PathBuf> {
for component in path.components() {
match component {
Component::Prefix(_) => unimplemented!("windows lol"),
Component::RootDir => {
}
Component::RootDir => {}
Component::CurDir => {}
Component::ParentDir => {
new_path.pop();