use std::fmt;
use std::io;
use std::num::TryFromIntError;
use crate::compaction::CompactionWorkerError;
use crate::tables::errors::BuilderError;
use crate::tables::errors::ReadError;
use crate::versioning;
use crate::versioning::errors::RecoverError;
pub type RainDBResult<T> = Result<T, RainDBError>;
#[derive(Clone, Debug, PartialEq)]
pub enum RainDBError {
IO(DBIOError),
Log(LogIOError),
Recovery(String),
TableCache(String),
TableRead(ReadError),
TableBuild(BuilderError),
Write(String),
VersionRecovery(versioning::errors::RecoverError),
Compaction(CompactionWorkerError),
KeyParsing(String),
PathResolution(String),
KeyNotFound,
Destruction(String),
Other(String),
}
impl std::error::Error for RainDBError {}
impl fmt::Display for RainDBError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RainDBError::IO(base_err) => write!(f, "{}", base_err),
RainDBError::Log(base_err) => write!(f, "{}", base_err),
RainDBError::Recovery(base_err) => write!(f, "{}", base_err),
RainDBError::TableCache(base_err) => write!(f, "{}", base_err),
RainDBError::TableRead(base_err) => write!(f, "{}", base_err),
RainDBError::TableBuild(base_err) => write!(f, "{}", base_err),
RainDBError::Write(base_err) => write!(f, "{}", base_err),
RainDBError::VersionRecovery(base_err) => write!(f, "{}", base_err),
RainDBError::Compaction(base_err) => write!(f, "{}", base_err),
RainDBError::KeyParsing(base_err) => write!(f, "{}", base_err),
RainDBError::PathResolution(base_err) => write!(f, "{}", base_err),
RainDBError::KeyNotFound => {
write!(f, "The specified key could not be found in the database.")
}
RainDBError::Destruction(base_err) => write!(
f,
"Failed to delete the database due to the following error: {}",
base_err
),
RainDBError::Other(base_err) => write!(f, "{}", base_err),
}
}
}
impl From<io::Error> for RainDBError {
fn from(err: io::Error) -> Self {
RainDBError::IO(err.into())
}
}
impl From<LogIOError> for RainDBError {
fn from(err: LogIOError) -> Self {
RainDBError::Log(err)
}
}
impl From<ReadError> for RainDBError {
fn from(err: ReadError) -> Self {
RainDBError::TableRead(err)
}
}
impl From<BuilderError> for RainDBError {
fn from(err: BuilderError) -> Self {
RainDBError::TableBuild(err)
}
}
impl From<CompactionWorkerError> for RainDBError {
fn from(err: CompactionWorkerError) -> Self {
RainDBError::Compaction(err)
}
}
impl From<RecoverError> for RainDBError {
fn from(err: RecoverError) -> Self {
RainDBError::VersionRecovery(err)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct LogCorruptionErrorMetadata {
bytes_corrupted: u64,
reason: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum LogIOError {
IO(DBIOError),
Corruption(LogCorruptionErrorMetadata),
Seralization(LogSerializationErrorKind),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum LogSerializationErrorKind {
FromInt(TryFromIntError),
Other(String),
}
impl std::error::Error for LogIOError {}
impl fmt::Display for LogIOError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LogIOError::IO(base_err) => write!(f, "{}", base_err),
LogIOError::Corruption(err_metadata) => write!(f, "{:?}", err_metadata),
LogIOError::Seralization(err_metadata) => write!(f, "{:?}", err_metadata),
}
}
}
impl From<io::Error> for LogIOError {
fn from(err: io::Error) -> Self {
LogIOError::IO(err.into())
}
}
impl From<TryFromIntError> for LogIOError {
fn from(err: TryFromIntError) -> Self {
LogIOError::Seralization(LogSerializationErrorKind::FromInt(err))
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DBIOError {
error_kind: io::ErrorKind,
custom_message: String,
}
impl DBIOError {
pub(crate) fn new(error_kind: io::ErrorKind, custom_message: String) -> Self {
Self {
error_kind,
custom_message,
}
}
pub(crate) fn kind(&self) -> io::ErrorKind {
self.error_kind
}
}
impl std::error::Error for DBIOError {}
impl fmt::Display for DBIOError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"error kind: {}. custom message: {}",
self.error_kind, self.custom_message
)
}
}
impl From<io::Error> for DBIOError {
fn from(io_err: io::Error) -> Self {
DBIOError {
error_kind: io_err.kind(),
custom_message: io_err.to_string(),
}
}
}