use core::{
error::Error,
fmt::{self, Debug, Display},
};
use bincode::config::Configuration;
use crate::{Repository, Storage, Unifier};
#[cfg(feature = "atomic")]
use crate::transaction::TransactionError;
#[derive(Debug, PartialEq, Eq)]
pub struct BufferOverflowError;
impl Display for BufferOverflowError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{self:?}")
}
}
impl Error for BufferOverflowError {}
pub struct BufferOverflowOr<E>(pub Option<E>);
impl<E> BufferOverflowOr<E> {
pub fn overflow(_: BufferOverflowError) -> Self {
BufferOverflowOr(None)
}
}
impl<E> From<E> for BufferOverflowOr<E> {
fn from(e: E) -> Self {
BufferOverflowOr(Some(e))
}
}
impl<E: Debug> Debug for BufferOverflowOr<E> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.0 {
Some(ref e) => write!(f, "Error({e:?})"),
None => write!(f, "BufferOverflow"),
}
}
}
impl<E: Display> Display for BufferOverflowOr<E> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.0 {
Some(ref e) => e.fmt(f),
None => Display::fmt(&BufferOverflowError, f),
}
}
}
impl<E: Display + Debug> Error for BufferOverflowOr<E> {}
pub enum DatabaseError<S: Storage> {
Storage(<S::Repo as Repository>::Error),
KeySerialization(<S::KeyUnifier as Unifier>::SerError),
ValueSerialization(<S::ValueUnifier as Unifier>::SerError),
KeyDeserialization(<S::KeyUnifier as Unifier>::DeError),
ValueDeserialization(<S::ValueUnifier as Unifier>::DeError),
FailedToIncrement,
Internal(InternalDatabaseError),
}
impl<S: Storage> Debug for DatabaseError<S>
where
<S::Repo as Repository>::Error: Debug,
<S::KeyUnifier as Unifier>::SerError: Debug,
<S::ValueUnifier as Unifier>::SerError: Debug,
<S::KeyUnifier as Unifier>::DeError: Debug,
<S::ValueUnifier as Unifier>::DeError: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Storage(e) => f.debug_tuple("Storage").field(e).finish(),
Self::KeySerialization(e) => f.debug_tuple("Serialization").field(e).finish(),
Self::ValueSerialization(e) => f.debug_tuple("ValueSerialization").field(e).finish(),
Self::KeyDeserialization(e) => f.debug_tuple("KeyDeserialization").field(e).finish(),
Self::ValueDeserialization(e) => {
f.debug_tuple("ValueDeserialization").field(e).finish()
}
Self::FailedToIncrement => write!(f, "FailedToIncrement"),
Self::Internal(e) => f.debug_tuple("Internal").field(e).finish(),
}
}
}
#[derive(Debug)]
pub enum InternalDatabaseError {
InvalidScope,
UnexpectedScopeInIndex,
MissingIndexEntry,
Serialization(<Configuration as Unifier>::SerError),
Deserialization(<Configuration as Unifier>::DeError),
}
impl<S> DatabaseError<S>
where
S: Storage,
{
pub(crate) fn from_buffer_overflow_or(
e: BufferOverflowOr<<S::KeyUnifier as Unifier>::SerError>,
) -> Self {
match e.0 {
Some(err) => DatabaseError::KeySerialization(err),
None => DatabaseError::Storage(BufferOverflowError.into()),
}
}
#[cfg(feature = "atomic")]
pub(crate) fn from_transaction_error(
e: TransactionError<
<S::KeyUnifier as Unifier>::SerError,
<S::ValueUnifier as Unifier>::SerError,
>,
) -> Self {
match e {
TransactionError::KeySerialization(err) => DatabaseError::KeySerialization(err),
TransactionError::ValueSerialization(err) => DatabaseError::ValueSerialization(err),
TransactionError::BufferOverflow => DatabaseError::Storage(BufferOverflowError.into()),
}
}
}
impl<S: Storage> From<InternalDatabaseError> for DatabaseError<S> {
fn from(e: InternalDatabaseError) -> Self {
DatabaseError::Internal(e)
}
}
impl<S: Storage> fmt::Display for DatabaseError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::Storage(ref s) => write!(f, "Storage error: {s}"),
Self::KeySerialization(ref e) => write!(f, "Key serialization error: {e}"),
Self::ValueSerialization(ref e) => write!(f, "Value serialization error: {e}"),
Self::KeyDeserialization(ref e) => write!(f, "Key deserialization error: {e}"),
Self::ValueDeserialization(ref e) => write!(f, "Value deserialization error: {e}"),
Self::FailedToIncrement => write!(f, "Failed to increment key value"),
Self::Internal(ref e) => write!(f, "Internal database error: {e}"),
}
}
}
impl fmt::Display for InternalDatabaseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::InvalidScope => write!(f, "Invalid scope"),
Self::UnexpectedScopeInIndex => write!(f, "Unexpected scope in index"),
Self::MissingIndexEntry => write!(f, "Missing index entry"),
Self::Serialization(ref e) => write!(f, "Serialization error: {e}"),
Self::Deserialization(ref e) => write!(f, "Deserialization error: {e}"),
}
}
}
impl<S: Storage + Debug> Error for DatabaseError<S> {}