use std::fmt::Display; use serde::{Deserialize, Serialize}; #[derive(Debug, thiserror::Error, Deserialize, Serialize)] pub enum InstanceError { #[error("registration failed")] RegistrationFailure, #[error("authentication failed")] AuthenticationFailed, } #[derive(Debug, thiserror::Error, Serialize, Deserialize)] pub enum RepositoryError {} #[derive(Debug, thiserror::Error, Deserialize, Serialize)] pub enum UserError {} #[derive(Debug, thiserror::Error, Serialize, Deserialize)] pub enum GetValueError { #[error("invalid object")] InvalidObject, } #[derive(Debug, thiserror::Error)] #[error("unauthorized")] pub struct UnauthorizedError; #[derive(Debug, thiserror::Error)] pub enum OperationError { #[error("the operation was handled but an error occurred")] Operation(#[from] B), #[error("an internal error occurred: {0:?}")] Internal(anyhow::Error), #[error("the operation was unhandled or unrecognized")] Unhandled, } pub trait IntoInternalError: Sized { fn as_internal_error(self) -> Result>; fn as_internal_error_with_context(self, context: C) -> Result> where C: Display + Send + Sync + 'static, { let internal_error = self.as_internal_error::(); match internal_error { Ok(success) => Ok(success), Err(OperationError::Internal(internal)) => { Err(OperationError::Internal(internal.context(context))) } _ => unreachable!(), } } } impl, T> IntoInternalError for Result { fn as_internal_error(self) -> Result> { match self { Ok(success) => Ok(success), Err(err) => Err(OperationError::Internal(err.into())), } } } impl OperationError { pub fn into_network(self) -> NetworkOperationError { match self { OperationError::Operation(operation_error) => { NetworkOperationError::Operation(operation_error) } OperationError::Internal(_) => NetworkOperationError::Internal, OperationError::Unhandled => NetworkOperationError::Unhandled, } } } #[derive(Debug, thiserror::Error)] #[error("an extractor failed with an error {0}")] pub struct ExtractorError>(#[from] pub E); impl> IntoInternalError for ExtractorError { fn as_internal_error(self) -> Result> { todo!() } } #[derive(Serialize, Deserialize, Debug, thiserror::Error)] pub enum NetworkOperationError { #[error("the operation was handled but an error occurred")] Operation(#[from] B), #[error("internal error")] Internal, #[error("the operation was unhandled or unrecognized")] Unhandled, }