Exit status now depends on Result
This commit is contained in:
parent
b8d2be4abe
commit
53041af73c
5 changed files with 59 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
||||||
use std::path::PathBuf;
|
use std::{fmt, iter, path::PathBuf};
|
||||||
|
|
||||||
/// Result convenience type for the Error type
|
/// Result convenience type for the Error type
|
||||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
@ -10,6 +10,9 @@ pub enum Error {
|
||||||
#[error("IO error: {0}")]
|
#[error("IO error: {0}")]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
|
||||||
|
#[error("Path doesn't exist: {0}")]
|
||||||
|
FileDoesntExist(PathBuf),
|
||||||
|
|
||||||
#[error("Could not open file {0:?}: {1}")]
|
#[error("Could not open file {0:?}: {1}")]
|
||||||
OpenFile(PathBuf, std::io::Error),
|
OpenFile(PathBuf, std::io::Error),
|
||||||
|
|
||||||
|
@ -36,6 +39,44 @@ pub enum Error {
|
||||||
|
|
||||||
#[error("Put error: {0}")]
|
#[error("Put error: {0}")]
|
||||||
Put(#[from] crate::ops::put::PutError),
|
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
|
/// Errors related to .trashinfo files
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
use garbage::{
|
use garbage::{
|
||||||
ops::{self, EmptyOptions, ListOptions, PutOptions, RestoreOptions},
|
ops::{self, EmptyOptions, ListOptions, PutOptions, RestoreOptions},
|
||||||
Result,
|
Result,
|
||||||
|
@ -61,7 +66,8 @@ fn main() {
|
||||||
match run(opt.command) {
|
match run(opt.command) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Error: {}", err);
|
error!("{}", err);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use libmount::mountinfo::Parser;
|
|
||||||
use libc::c_ulong;
|
use libc::c_ulong;
|
||||||
|
use libmount::mountinfo::Parser;
|
||||||
|
|
||||||
use crate::errors::Error;
|
use crate::errors::Error;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
|
@ -65,11 +65,13 @@ pub struct PutOptions {
|
||||||
|
|
||||||
/// Throw some files into the trash.
|
/// Throw some files into the trash.
|
||||||
pub fn put(options: PutOptions) -> Result<()> {
|
pub fn put(options: PutOptions) -> Result<()> {
|
||||||
|
let mut errors = vec![];
|
||||||
|
|
||||||
for path in options.paths.iter() {
|
for path in options.paths.iter() {
|
||||||
let abs_path = utils::into_absolute(&path)?;
|
let abs_path = utils::into_absolute(&path)?;
|
||||||
|
|
||||||
if !abs_path.exists() {
|
if !abs_path.exists() {
|
||||||
error!("Skipping non-existent path {:?}", path);
|
errors.push(Error::FileDoesntExist(path.clone()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +104,11 @@ pub fn put(options: PutOptions) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::multiple(errors.into_iter()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DeletionStrategy describes a strategy by which a file is deleted
|
/// DeletionStrategy describes a strategy by which a file is deleted
|
||||||
|
|
|
@ -24,8 +24,7 @@ pub fn into_absolute(path: impl AsRef<Path>) -> Result<PathBuf> {
|
||||||
for component in path.components() {
|
for component in path.components() {
|
||||||
match component {
|
match component {
|
||||||
Component::Prefix(_) => unimplemented!("windows lol"),
|
Component::Prefix(_) => unimplemented!("windows lol"),
|
||||||
Component::RootDir => {
|
Component::RootDir => {}
|
||||||
}
|
|
||||||
Component::CurDir => {}
|
Component::CurDir => {}
|
||||||
Component::ParentDir => {
|
Component::ParentDir => {
|
||||||
new_path.pop();
|
new_path.pop();
|
||||||
|
|
Loading…
Reference in a new issue