use std::error::Error;
use std::fmt;
use crate::database::error::DatabaseError;
#[derive(Debug)]
pub enum KeyStoreError {
OperationError {
context: String,
source: Box<dyn Error>,
},
#[allow(dead_code)]
QueryError {
context: String,
source: Box<dyn Error>,
},
StorageError {
context: String,
source: Box<dyn Error>,
},
ConnectionError(Box<dyn Error>),
NotFoundError(String),
DuplicateKeyError(String),
UserDoesNotExistError(String),
}
impl Error for KeyStoreError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
KeyStoreError::OperationError { source, .. } => Some(&**source),
KeyStoreError::QueryError { source, .. } => Some(&**source),
KeyStoreError::StorageError { source, .. } => Some(&**source),
KeyStoreError::ConnectionError(err) => Some(&**err),
KeyStoreError::NotFoundError(_) => None,
KeyStoreError::DuplicateKeyError(_) => None,
KeyStoreError::UserDoesNotExistError(_) => None,
}
}
}
impl fmt::Display for KeyStoreError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
KeyStoreError::OperationError { context, source } => {
write!(f, "failed to perform operation: {}: {}", context, source)
}
KeyStoreError::QueryError { context, source } => {
write!(f, "failed query: {}: {}", context, source)
}
KeyStoreError::StorageError { context, source } => write!(
f,
"the underlying storage returned an error: {}: {}",
context, source
),
KeyStoreError::ConnectionError(err) => {
write!(f, "failed to connect to underlying storage: {}", err)
}
KeyStoreError::NotFoundError(msg) => write!(f, "key not found: {}", msg),
KeyStoreError::DuplicateKeyError(msg) => write!(f, "key already exists: {}", msg),
KeyStoreError::UserDoesNotExistError(msg) => write!(f, "user does not exist: {}", msg),
}
}
}
impl From<DatabaseError> for KeyStoreError {
fn from(err: DatabaseError) -> KeyStoreError {
match err {
DatabaseError::ConnectionError(_) => KeyStoreError::ConnectionError(Box::new(err)),
_ => KeyStoreError::StorageError {
context: "The database returned an error".to_string(),
source: Box::new(err),
},
}
}
}