use crate::alloc::{boxed::Box, string::String};
#[cfg(feature = "std")]
use thiserror::Error;
use crate::callback::CallbackError;
use crate::validate::ValidationError;
use core::fmt;
#[non_exhaustive]
pub enum MechanismErrorKind {
Parse,
Protocol,
Outcome,
}
#[cfg(feature = "std")]
pub trait MechanismError: fmt::Debug + fmt::Display + Send + Sync + std::error::Error {
fn kind(&self) -> MechanismErrorKind;
}
#[cfg(not(feature = "std"))]
pub trait MechanismError: fmt::Debug + fmt::Display + Send + Sync {
fn kind(&self) -> MechanismErrorKind;
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum SessionError {
#[error("IO error occurred")]
Io {
#[from]
source: crate::io::Error,
},
#[cfg(feature = "provider_base64")]
#[error("base64 wrapping failed")]
Base64 {
#[from]
source: base64::DecodeError,
},
#[error("no security layer is installed")]
NoSecurityLayer,
#[error("input data was required but not provided")]
InputDataRequired,
#[error("step was called after mechanism finished")]
MechanismDone,
#[error("internal mechanism error: {0}")]
MechanismError(Box<dyn MechanismError>),
#[error("callback error")]
CallbackError(
#[from]
#[source]
CallbackError,
),
#[error("validation error")]
ValidationError(
#[from]
#[source]
ValidationError,
),
#[error(transparent)]
#[cfg(feature = "std")]
Boxed(#[from] Box<dyn std::error::Error + Send + Sync>),
#[error("callback did not validate the authentication exchange")]
NoValidate,
#[error("the server failed mutual authentication")]
MutualAuthenticationFailed,
#[error("channel binding data for '{0}' is required")]
MissingChannelBindingData(String),
}
impl SessionError {
#[must_use]
pub const fn input_required() -> Self {
Self::InputDataRequired
}
#[must_use]
pub const fn is_mechanism_error(&self) -> bool {
matches!(self, Self::MechanismError(_))
}
#[must_use]
pub const fn is_missing_prop(&self) -> bool {
matches!(self, Self::CallbackError(CallbackError::NoCallback(_)))
}
}
impl<T: MechanismError + 'static> From<T> for SessionError {
fn from(e: T) -> Self {
Self::MechanismError(Box::new(e))
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum SASLError {
#[error("no shared mechanism found")]
NoSharedMechanism,
}
#[cfg(test)]
mod tests {
use super::*;
static_assertions::assert_impl_all!(SessionError: Send, Sync);
static_assertions::assert_obj_safe!(MechanismError);
}