use bincode::Error as SerialisationError;
use ffi_utils::{ErrorCode, StringError};
use futures::channel::mpsc::SendError;
use safe_core::ffi::error_codes::*;
use safe_core::ipc::IpcError;
use safe_core::nfs::NfsError;
use safe_core::CoreError;
use safe_core::{core_error_code, safe_nd_error_core};
use safe_nd::Error as SndError;
use std::ffi::NulError;
use std::fmt::{self, Display, Formatter};
use std::io::Error as IoError;
use std::str::Utf8Error;
use std::string::FromUtf8Error;
use std::sync::mpsc::RecvError;
pub type Result<T> = std::result::Result<T, AuthError>;
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum AuthError {
Unexpected(String),
CoreError(CoreError),
SndError(SndError),
IoError(IoError),
NfsError(NfsError),
EncodeDecodeError,
IpcError(IpcError),
AccountContainersCreation(String),
NoSuchContainer(String),
PendingRevocation,
}
impl ErrorCode for AuthError {
fn error_code(&self) -> i32 {
match *self {
AuthError::CoreError(ref err) => core_error_code(err),
AuthError::SndError(ref err) => safe_nd_error_core(err),
AuthError::IpcError(ref err) => match *err {
IpcError::AuthDenied => ERR_AUTH_DENIED,
IpcError::ContainersDenied => ERR_CONTAINERS_DENIED,
IpcError::InvalidMsg => ERR_INVALID_MSG,
IpcError::EncodeDecodeError => ERR_ENCODE_DECODE_ERROR,
IpcError::AlreadyAuthorised => ERR_ALREADY_AUTHORISED,
IpcError::UnknownApp => ERR_UNKNOWN_APP,
IpcError::Unexpected(_) => ERR_UNEXPECTED,
IpcError::StringError(_) => ERR_STRING_ERROR,
IpcError::ShareMDataDenied => ERR_SHARE_MDATA_DENIED,
IpcError::InvalidOwner(..) => ERR_INVALID_OWNER,
IpcError::IncompatibleMockStatus => ERR_INCOMPATIBLE_MOCK_STATUS,
},
AuthError::NfsError(ref err) => match *err {
NfsError::CoreError(ref err) => core_error_code(err),
NfsError::FileExists => ERR_FILE_EXISTS,
NfsError::FileNotFound => ERR_FILE_NOT_FOUND,
NfsError::InvalidRange => ERR_INVALID_RANGE,
NfsError::EncodeDecodeError(_) => ERR_ENCODE_DECODE_ERROR,
NfsError::SelfEncryption(_) => ERR_SELF_ENCRYPTION,
NfsError::Unexpected(_) => ERR_UNEXPECTED,
},
AuthError::EncodeDecodeError => ERR_ENCODE_DECODE_ERROR,
AuthError::IoError(_) => ERR_IO_ERROR,
AuthError::AccountContainersCreation(_) => 1, AuthError::NoSuchContainer(_) => ERR_NO_SUCH_CONTAINER,
AuthError::PendingRevocation => 2, AuthError::Unexpected(_) => ERR_UNEXPECTED,
}
}
}
impl Display for AuthError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match *self {
Self::Unexpected(ref error) => {
write!(formatter, "Unexpected (probably a logic error): {}", error)
}
Self::CoreError(ref error) => write!(formatter, "Core error: {}", error),
Self::SndError(ref error) => write!(formatter, "Safe ND error: {}", error),
Self::IoError(ref error) => write!(formatter, "I/O error: {}", error),
Self::NfsError(ref error) => write!(formatter, "NFS error: {:?}", error),
Self::EncodeDecodeError => write!(formatter, "Serialisation error"),
Self::IpcError(ref error) => write!(formatter, "IPC error: {:?}", error),
Self::AccountContainersCreation(ref reason) => write!(
formatter,
"Account containers creation error: {}. Login to attempt recovery.",
reason
),
Self::NoSuchContainer(ref name) => {
write!(formatter, "'{}' not found in the access container", name)
}
Self::PendingRevocation => write!(
formatter,
"Couldn't authenticate app that is pending revocation"
),
}
}
}
impl Into<IpcError> for AuthError {
fn into(self) -> IpcError {
match self {
Self::Unexpected(desc) => IpcError::Unexpected(desc),
Self::IpcError(err) => err,
err => IpcError::Unexpected(format!("{:?}", err)),
}
}
}
impl From<SendError> for AuthError {
fn from(error: SendError) -> Self {
Self::Unexpected(error.to_string())
}
}
impl From<CoreError> for AuthError {
fn from(error: CoreError) -> Self {
Self::CoreError(error)
}
}
impl From<IpcError> for AuthError {
fn from(error: IpcError) -> Self {
Self::IpcError(error)
}
}
impl From<RecvError> for AuthError {
fn from(error: RecvError) -> Self {
Self::from(error.to_string())
}
}
impl From<NulError> for AuthError {
fn from(error: NulError) -> Self {
Self::from(error.to_string())
}
}
impl From<IoError> for AuthError {
fn from(error: IoError) -> Self {
Self::IoError(error)
}
}
impl From<SndError> for AuthError {
fn from(error: SndError) -> Self {
Self::SndError(error)
}
}
impl<'a> From<&'a str> for AuthError {
fn from(error: &'a str) -> Self {
Self::Unexpected(error.to_owned())
}
}
impl From<String> for AuthError {
fn from(error: String) -> Self {
Self::Unexpected(error)
}
}
impl From<NfsError> for AuthError {
fn from(error: NfsError) -> Self {
Self::NfsError(error)
}
}
impl From<SerialisationError> for AuthError {
fn from(_err: SerialisationError) -> Self {
Self::EncodeDecodeError
}
}
impl From<Utf8Error> for AuthError {
fn from(_err: Utf8Error) -> Self {
Self::EncodeDecodeError
}
}
impl From<FromUtf8Error> for AuthError {
fn from(_err: FromUtf8Error) -> Self {
Self::EncodeDecodeError
}
}
impl From<StringError> for AuthError {
fn from(_err: StringError) -> Self {
Self::EncodeDecodeError
}
}