use std::{fmt, result};
use std::error::Error;
use crate::serializer::{SerializerError, SerializerErrorKind};
use crate::storage::{StorageError, StorageErrorKind};
#[derive(Debug)]
pub struct IndexError(Box<RawIndexError>);
#[derive(Debug)]
struct RawIndexError {
kind: IndexErrorKind,
source: Option<Box<dyn std::error::Error + Send + Sync>>,
}
impl IndexError {
pub(crate) fn not_found() -> Self {
Self(Box::new(RawIndexError {
kind: IndexErrorKind::NotFound,
source: None,
}))
}
pub(crate) fn syntax<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawIndexError {
kind: IndexErrorKind::Syntax,
source: Some(error.into()),
}))
}
pub(crate) fn storage_corrupted<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawIndexError {
kind: IndexErrorKind::StorageCorrupted,
source: Some(error.into()),
}))
}
pub(crate) fn io<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawIndexError {
kind: IndexErrorKind::Io,
source: Some(error.into()),
}))
}
pub(crate) fn other<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawIndexError {
kind: IndexErrorKind::Other,
source: Some(error.into()),
}))
}
pub fn kind(&self) -> IndexErrorKind {
self.0.kind
}
pub fn is_not_found(&self) -> bool {
IndexErrorKind::NotFound == self.0.kind
}
pub fn is_syntax(&self) -> bool {
IndexErrorKind::Syntax == self.0.kind
}
pub fn is_storage_corrupted(&self) -> bool {
IndexErrorKind::StorageCorrupted == self.0.kind
}
pub fn is_io(&self) -> bool {
IndexErrorKind::Io == self.0.kind
}
pub fn is_other(&self) -> bool {
IndexErrorKind::Other == self.0.kind
}
}
impl Error for IndexError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self.0.source {
Some(ref source) => Some(&**source),
None => None
}
}
}
impl fmt::Display for IndexError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.kind.fmt(f)
}
}
impl From<StorageError> for IndexError {
fn from(error: StorageError) -> Self {
use StorageErrorKind::*;
match error.kind() {
InvalidUuid => Self::storage_corrupted(error),
Io => Self::io(error),
Other => Self::other(error),
NotFound => panic!("index file not found"),
}
}
}
impl From<SerializerError> for IndexError {
fn from(error: SerializerError) -> Self {
use SerializerErrorKind::*;
match error.kind() {
Syntax => Self::syntax(error),
Io => Self::io(error),
Other => Self::other(error)
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum IndexErrorKind {
NotFound,
Syntax,
StorageCorrupted,
Io,
Other,
}
impl fmt::Display for IndexErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use IndexErrorKind::*;
match self {
NotFound => write!(f, "value not found"),
Syntax => write!(f, "serialization/deserialization error"),
StorageCorrupted => write!(f, "storage is corrupted"),
Io => write!(f, "io error"),
Other => write!(f, "other error"),
}
}
}
pub type Result<T> = result::Result<T, IndexError>;