sett 0.4.0

Rust port of sett (data compression, encryption and transfer tool).
Documentation
//! Error namespace

use crate::openpgp::error::PgpError;

/// I/O error including info about the involved file name
#[derive(Debug)]
pub struct FileIoError<S, E> {
    /// file name
    pub file: S,
    /// Lower level cause
    pub source: E,
}

impl<E: std::fmt::Display, S: std::fmt::Display> std::fmt::Display for FileIoError<S, E> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}: {}", self.file, self.source)
    }
}
impl<S: std::fmt::Display + std::fmt::Debug, E: std::fmt::Display + std::fmt::Debug>
    std::error::Error for FileIoError<S, E>
{
}

/// Error related to package metadata
#[derive(Debug)]
pub enum MetadataError<E> {
    /// Reader error
    Read(crate::zip::error::ReadStreamError<E>),
    /// json deserialization error
    Deserialize(serde_json::Error),
}

impl<E> std::fmt::Display for MetadataError<E> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Metadata error")
    }
}

impl<E: core::error::Error + 'static> std::error::Error for MetadataError<E> {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::Read(source) => Some(source),
            Self::Deserialize(source) => Some(source),
        }
    }
}
impl<E> From<crate::zip::error::ReadStreamError<E>> for MetadataError<E> {
    fn from(value: crate::zip::error::ReadStreamError<E>) -> Self {
        Self::Read(value)
    }
}
impl<E> From<serde_json::Error> for MetadataError<E> {
    fn from(value: serde_json::Error) -> Self {
        Self::Deserialize(value)
    }
}

/// Error occurring when deserializing a purpose
#[derive(Debug)]
pub struct InvalidPurposeError(pub String);
impl std::fmt::Display for InvalidPurposeError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Invalid purpose: {}", self.0)
    }
}
impl std::error::Error for InvalidPurposeError {}

/// Error occurring when verifying a package
#[derive(Debug)]
pub enum VerificationError<E> {
    /// Package contains unexpected files
    UnexpectedFiles(&'static [&'static str]),
    /// The package is missing some required files
    MissingFiles(Vec<String>, &'static [&'static str]),
    /// Invalid metadata
    Metadata(MetadataError<E>),
    /// Signature verification error
    Signature(PgpError),
}
impl<E> std::fmt::Display for VerificationError<E> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let error_msg_base = |expected: &[&str]| {
            format!(
                "A valid data package must contain exactly the following {} files: {}",
                expected.len(),
                expected.join(", ")
            )
        };
        match self {
            Self::UnexpectedFiles(expected) => write!(
                f,
                "invalid data package. Zip archive contains unexpected \
                    files. {}.",
                error_msg_base(expected)
            ),
            Self::MissingFiles(files, expected) => write!(
                f,
                "invalid data package. Zip archive is missing the following \
            files: {}. {}.",
                files.join(", "),
                error_msg_base(expected)
            ),
            Self::Signature(err) => write!(f, "{err}"),
            _ => write!(f, "Package verification error"),
        }
    }
}
impl<E: core::error::Error + 'static> std::error::Error for VerificationError<E> {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::Metadata(source) => Some(source),
            Self::Signature(source) => Some(source),
            _ => None,
        }
    }
}
impl<E> From<MetadataError<E>> for VerificationError<E> {
    fn from(value: MetadataError<E>) -> Self {
        Self::Metadata(value)
    }
}
impl<E> From<crate::zip::error::ReadStreamError<E>> for VerificationError<E> {
    fn from(value: crate::zip::error::ReadStreamError<E>) -> Self {
        Self::Metadata(value.into())
    }
}
impl<E> From<PgpError> for VerificationError<E> {
    fn from(value: PgpError) -> Self {
        Self::Signature(value)
    }
}