#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::borrow::Cow;
#[cfg(feature = "std")]
use std::fmt;
#[cfg(not(feature = "std"))]
use core::fmt;
use dcrypt_api::{Error as CoreError, Result as CoreResult};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
Parameter {
name: Cow<'static, str>, reason: Cow<'static, str>, },
Length {
context: &'static str,
expected: usize,
actual: usize,
},
Authentication {
algorithm: &'static str,
},
NotImplemented {
feature: &'static str,
},
Processing {
operation: &'static str,
details: &'static str,
},
MacError {
algorithm: &'static str,
details: &'static str,
},
#[cfg(feature = "std")]
External {
source: &'static str,
details: String,
},
#[cfg(not(feature = "std"))]
External {
source: &'static str,
},
Other(&'static str),
}
impl Error {
pub fn param<N: Into<Cow<'static, str>>, R: Into<Cow<'static, str>>>(
name: N,
reason: R,
) -> Self {
Error::Parameter {
name: name.into(),
reason: reason.into(),
}
}
}
pub type Result<T> = core::result::Result<T, Error>;
pub type CipherResult<T> = Result<T>;
pub type HashResult<T> = Result<T>;
pub type MacResult<T> = Result<T>;
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Parameter { name, reason } => {
write!(f, "Invalid parameter '{}': {}", name, reason)
}
Error::Length {
context,
expected,
actual,
} => {
write!(
f,
"Invalid length for {}: expected {}, got {}",
context, expected, actual
)
}
Error::Authentication { algorithm } => {
write!(f, "Authentication failed for {}", algorithm)
}
Error::NotImplemented { feature } => {
write!(f, "Feature not implemented: {}", feature)
}
Error::Processing { operation, details } => {
write!(f, "Processing error in {}: {}", operation, details)
}
Error::MacError { algorithm, details } => {
write!(f, "MAC error in {}: {}", algorithm, details)
}
#[cfg(feature = "std")]
Error::External { source, details } => {
write!(f, "External error from {}: {}", source, details)
}
#[cfg(not(feature = "std"))]
Error::External { source } => {
write!(f, "External error from {}", source)
}
Error::Other(msg) => write!(f, "{}", msg),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
impl From<Error> for CoreError {
fn from(err: Error) -> Self {
match err {
Error::Parameter { name, reason } => CoreError::InvalidParameter {
context: match name {
Cow::Borrowed(s) => s,
Cow::Owned(s) => Box::leak(s.into_boxed_str()),
},
#[cfg(feature = "std")]
message: reason.into_owned(),
},
Error::Length {
context,
expected,
actual,
} => CoreError::InvalidLength {
context,
expected,
actual,
},
Error::Authentication { algorithm } => CoreError::AuthenticationFailed {
context: algorithm,
#[cfg(feature = "std")]
message: "authentication failed".to_string(),
},
Error::NotImplemented { feature } => CoreError::NotImplemented { feature },
Error::Processing { operation, details } => CoreError::Other {
context: operation,
#[cfg(feature = "std")]
message: details.to_string(),
},
Error::MacError { algorithm, details } => CoreError::Other {
context: algorithm,
#[cfg(feature = "std")]
message: details.to_string(),
},
#[cfg(feature = "std")]
Error::External { source, details } => CoreError::Other {
context: source,
message: details,
},
#[cfg(not(feature = "std"))]
Error::External { source } => CoreError::Other {
context: source,
#[cfg(feature = "std")]
message: "external error".to_string(),
},
Error::Other(msg) => CoreError::Other {
context: "primitives",
#[cfg(feature = "std")]
message: msg.to_string(),
},
}
}
}
#[inline]
pub fn to_core_result<T>(r: Result<T>, ctx: &'static str) -> CoreResult<T> {
r.map_err(|e| {
let mut core = CoreError::from(e);
core = core.with_context(ctx);
core
})
}
pub use dcrypt_api::error::{ResultExt, SecureErrorHandling};
pub mod validate;