~iptq/garbage

[PATCH 1/3] Adds a new error type with a context for the causes of errors.

Details
Message ID
<AaJ7Ix5WYWvM712KOmC417sz8lfB4MrLSKXp8VnUFpw@cp3-web-020.plabs.ch>
DKIM signature
missing
Download raw message
Patch: +59 -17
---
 src/errors.rs      | 37 +++++++++++++++++++++++++++++++++++--
 src/info.rs        | 17 ++++++++++-------
 src/ops/put.rs     | 10 ++++++----
 src/ops/restore.rs | 12 ++++++++----
 4 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/src/errors.rs b/src/errors.rs
index 6346f97..9db81ae 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -1,12 +1,45 @@
use std::path::PathBuf;
use std::{
    fmt::{Display, Formatter, Result as FmtResult},
    path::PathBuf,
};

/// Result convenience type for the Error type
pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Errors plus their surrounding context.
#[derive(Debug, Error)]
pub struct Error {
    /// The cause of the error.
    #[source]
    pub kind: ErrorKind,

    /// A stack of things that were being done when the error occurred.
    pub context: Vec<String>,
}

impl Display for Error {
    fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
        writeln!(fmt, "{}", self.kind)?;
        for entry in self.context.iter().rev() {
            writeln!(fmt, "caused by {}", entry)?;
        }
        Ok(())
    }
}

impl<T: Into<ErrorKind>> From<T> for Error {
    fn from(kind: T) -> Error {
        Error {
            kind: kind.into(),
            context: Vec::new(),
        }
    }
}

/// All errors that could happen
#[derive(Debug, Error)]
#[allow(missing_docs)]
pub enum Error {
pub enum ErrorKind {
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

diff --git a/src/info.rs b/src/info.rs
index a52ae26..58b3e10 100644
--- a/src/info.rs
+++ b/src/info.rs
@@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
use chrono::{DateTime, Local, TimeZone};
use percent_encoding::percent_decode;

use crate::errors::{Error, TrashInfoError};
use crate::errors::{Error, ErrorKind, TrashInfoError};
use crate::utils;

const DATE_FORMAT: &str = "%Y-%m-%dT%H:%M:%S";
@@ -63,10 +63,11 @@ impl TrashInfo {
            // first line must be "[Trash Info]"
            if i == 0 {
                if line != "[Trash Info]" {
                    return Err(Error::BadTrashInfo(
                    return Err(ErrorKind::BadTrashInfo(
                        info_path,
                        TrashInfoError::MissingHeader,
                    ));
                    )
                    .into());
                } else {
                    continue;
                }
@@ -95,20 +96,22 @@ impl TrashInfo {
        let path = match path {
            Some(path) => path,
            None => {
                return Err(Error::BadTrashInfo(
                return Err(ErrorKind::BadTrashInfo(
                    info_path,
                    TrashInfoError::MissingPath,
                ))
                )
                .into())
            }
        };

        let deletion_date = match deletion_date {
            Some(deletion_date) => deletion_date,
            None => {
                return Err(Error::BadTrashInfo(
                return Err(ErrorKind::BadTrashInfo(
                    info_path,
                    TrashInfoError::MissingDate,
                ))
                )
                .into())
            }
        };

diff --git a/src/ops/put.rs b/src/ops/put.rs
index 6d42b7d..50bc2e6 100644
--- a/src/ops/put.rs
+++ b/src/ops/put.rs
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};

use chrono::Local;

use crate::errors::{Error, Result};
use crate::errors::{ErrorKind, Result};
use crate::utils::{self};
use crate::{TrashDir, TrashInfo};
use crate::{HOME_MOUNT, MOUNTS};
@@ -79,7 +79,7 @@ pub fn put(options: PutOptions) -> Result<()> {
            || (current_dir.parent().is_some()
                && abs_path == current_dir.parent().unwrap())
        {
            return Err(Error::Put(PutError::CannotTrashDotDirs));
            return Err(ErrorKind::Put(PutError::CannotTrashDotDirs).into());
        }

        // pick the best strategy for deleting this particular file
@@ -202,7 +202,7 @@ impl DeletionStrategy {
                }
            };
            if !should_continue {
                return Err(Error::Put(PutError::CancelledByUser));
                return Err(ErrorKind::Put(PutError::CancelledByUser).into());
            }
        }

@@ -213,7 +213,9 @@ impl DeletionStrategy {
        let elapsed_str = elapsed.to_string();
        let target_file = match target.file_name() {
            Some(file) => file.to_os_string(),
            None => return Err(Error::Put(PutError::InvalidFilename)),
            None => {
                return Err(ErrorKind::Put(PutError::InvalidFilename).into())
            }
        };
        let file_name = concat_os_str!(elapsed_str, ".", target_file);
        // {
diff --git a/src/ops/restore.rs b/src/ops/restore.rs
index 4103e91..c0d363e 100644
--- a/src/ops/restore.rs
+++ b/src/ops/restore.rs
@@ -3,7 +3,7 @@ use std::fs;
use std::io;
use std::path::PathBuf;

use crate::errors::{Error, Result};
use crate::errors::{ErrorKind, Result};
use crate::list;
use crate::TrashDir;

@@ -26,7 +26,10 @@ pub fn restore(options: RestoreOptions) -> Result<()> {
    let trash_dir = TrashDir::from_opt(options.trash_dir.as_ref());

    if trash_dir.check_info_dir()?.is_none() {
        return Err(Error::TrashDirDoesntExist(trash_dir.path().to_path_buf()));
        return Err(ErrorKind::TrashDirDoesntExist(
            trash_dir.path().to_path_buf(),
        )
        .into());
    }

    // get list of files sorted by deletion date
@@ -54,9 +57,10 @@ pub fn restore(options: RestoreOptions) -> Result<()> {
    };

    if files.len() == 0 {
        return Err(Error::NoFilesInThisDirectory(
        return Err(ErrorKind::NoFilesInThisDirectory(
            trash_dir.path().to_path_buf(),
        ));
        )
        .into());
    }

    list::print_files_list(files.iter(), true);
-- 
2.28.0
Reply to thread Export thread (mbox)