use core::panic;
use std::{borrow::Cow, fmt::Display, io, str};
use thiserror::Error;
use crate::id::{PersyId, RecRef};
pub(crate) type PERes<T> = Result<T, GenericError>;
#[cfg(feature = "unstable")]
use std::backtrace::Backtrace;
#[derive(Debug)]
pub enum PE<T: Into<PersyError>> {
PE(T),
}
impl<T: std::error::Error + Display + Into<PersyError>> std::error::Error for PE<T> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
PE::PE(e) => e.source(),
}
}
}
impl<T: Display + Into<PersyError>> Display for PE<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PE::PE(e) => e.fmt(f),
}
}
}
impl<T: Into<PersyError>> PE<T> {
pub fn error(self) -> T {
match self {
PE::PE(e) => e,
}
}
pub fn persy_error(self) -> PersyError {
match self {
PE::PE(e) => e.into(),
}
}
}
impl<T: Into<PersyError>> std::ops::Deref for PE<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
PE::PE(e) => e,
}
}
}
impl<S, D> From<S> for PE<D>
where
S: Into<D>,
D: Into<PersyError>,
S: Into<PersyError>,
{
fn from(source: S) -> Self {
PE::PE(source.into())
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum PersyError {
#[error("IO Error: {from} ")]
Io {
from: io::Error,
#[cfg(feature = "unstable")]
backtrace: Backtrace,
},
#[error("String decoding error: {0}")]
DecodingUtf8(str::Utf8Error),
#[error("Failure acquiring lock for poisoning")]
DecodingDataEncoding(data_encoding::DecodeError),
#[error("Version Not Latest")]
VersionNotLatest,
#[error("Record Not Found {0}")]
RecordNotFound(PersyId),
#[error("Segment Not Found")]
SegmentNotFound,
#[error("Segment Already Exists")]
SegmentAlreadyExists,
#[error("Index Already Exists")]
IndexAlreadyExists,
#[error("Create and drop of a segment in the same transaction is not allowed")]
CannotDropSegmentCreatedInTx,
#[error("Create and drop of a index in the same transaction is not allowed")]
CannotDropIndexCreatedInTx,
#[error("Index Not Found")]
IndexNotFound,
#[error("Index method type mismatch persistent types: {0}")]
IndexTypeMismatch(Cow<'static, str>),
#[error("Found duplicate key:{0} for index: {1}")]
IndexDuplicateKey(String, String),
#[error("Reached the limit of retry changing the index")]
ReachedLimitOfRetry,
#[error("Timeout acquiring the data locks for the transaction")]
TransactionTimeout,
#[error("The id '{0}' has no valid format")]
InvalidId(String),
#[error("The id '{0}' has no valid format")]
InvalidPersyId(RecRef),
#[error("{0}")]
InitError(String),
#[error("Failure acquiring file lock: {0}")]
AlreadyInUse(io::Error),
#[error("File do not exists")]
NotExists,
#[error("Cannot create a new file already exists")]
AlreadyExists,
#[error("The file specified is not a Persy file")]
NotPersyFile,
#[error("Size of the record is too big")]
RecordToBig,
#[error("The key or the value are over the allowed size limit")]
KeyOrValueTooBig,
#[error("Varint Decoding error: {0}")]
VarIntError(#[from] unsigned_varint::io::ReadError),
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum BeginTransactionError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Transaction Id must be maximum 512 bytes")]
InvalidTransactionId,
}
impl From<BeginTransactionError> for PersyError {
fn from(e: BeginTransactionError) -> Self {
match e {
BeginTransactionError::Generic(e) => e.into(),
BeginTransactionError::InvalidTransactionId => {
PersyError::InvalidId("Transaction Id must be maximum 512 bytes".to_owned())
}
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CreateSegmentError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Segment Already Exists")]
SegmentAlreadyExists,
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum DropIndexError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Index Not Found")]
IndexNotFound,
#[error("Create and drop of a index in the same transaction is not allowed")]
CannotDropIndexCreatedInTx,
}
impl From<DropSegmentError> for DropIndexError {
fn from(e: DropSegmentError) -> Self {
match e {
DropSegmentError::Generic(ee) => DropIndexError::Generic(ee),
DropSegmentError::SegmentNotFound => DropIndexError::IndexNotFound,
DropSegmentError::CannotDropSegmentCreatedInTx => DropIndexError::CannotDropIndexCreatedInTx,
}
}
}
impl From<DropIndexError> for PersyError {
fn from(e: DropIndexError) -> Self {
match e {
DropIndexError::Generic(e) => e.into(),
DropIndexError::IndexNotFound => PersyError::IndexNotFound,
DropIndexError::CannotDropIndexCreatedInTx => PersyError::CannotDropIndexCreatedInTx,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum DropSegmentError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Segment Not Found")]
SegmentNotFound,
#[error("Create and drop of a segment in the same transaction is not allowed")]
CannotDropSegmentCreatedInTx,
}
impl From<SegmentError> for DropSegmentError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(ee) => DropSegmentError::Generic(ee),
SegmentError::SegmentNotFound => DropSegmentError::SegmentNotFound,
}
}
}
impl From<DropSegmentError> for PersyError {
fn from(e: DropSegmentError) -> Self {
match e {
DropSegmentError::Generic(e) => e.into(),
DropSegmentError::SegmentNotFound => PersyError::SegmentNotFound,
DropSegmentError::CannotDropSegmentCreatedInTx => PersyError::CannotDropSegmentCreatedInTx,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum SegmentError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Segment Not Found")]
SegmentNotFound,
}
impl From<SegmentError> for PersyError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(e) => e.into(),
SegmentError::SegmentNotFound => PersyError::SegmentNotFound,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum ReadError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Segment Not Found")]
SegmentNotFound,
#[error("The id '{0}' has no valid format")]
InvalidPersyId(RecRef),
}
impl From<ReadError> for PersyError {
fn from(e: ReadError) -> Self {
match e {
ReadError::Generic(e) => e.into(),
ReadError::SegmentNotFound => PersyError::SegmentNotFound,
ReadError::InvalidPersyId(e) => PersyError::InvalidPersyId(e),
}
}
}
impl From<SegmentError> for ReadError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(e) => ReadError::Generic(e),
SegmentError::SegmentNotFound => ReadError::SegmentNotFound,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CreateIndexError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Index Already Exists")]
IndexAlreadyExists,
}
impl From<CreateSegmentError> for CreateIndexError {
fn from(e: CreateSegmentError) -> Self {
match e {
CreateSegmentError::Generic(ee) => CreateIndexError::Generic(ee),
CreateSegmentError::SegmentAlreadyExists => CreateIndexError::IndexAlreadyExists,
}
}
}
impl From<InsertError> for CreateIndexError {
fn from(e: InsertError) -> Self {
match e {
InsertError::Generic(ee) => CreateIndexError::Generic(ee),
InsertError::SegmentNotFound => panic!("Segment should be created while creating index, impossible error"),
InsertError::RecordToBig => panic!("Record size should never fail in index creation"),
}
}
}
impl From<CreateIndexError> for PersyError {
fn from(e: CreateIndexError) -> Self {
match e {
CreateIndexError::Generic(er) => er.into(),
CreateIndexError::IndexAlreadyExists => PersyError::IndexAlreadyExists,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum IndexError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Index Not Found")]
IndexNotFound,
}
impl From<IndexError> for PersyError {
fn from(e: IndexError) -> Self {
match e {
IndexError::Generic(e) => e.into(),
IndexError::IndexNotFound => PersyError::IndexNotFound,
}
}
}
impl From<SegmentError> for IndexError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(ex) => IndexError::Generic(ex),
SegmentError::SegmentNotFound => IndexError::IndexNotFound,
}
}
}
impl From<ReadError> for IndexError {
fn from(e: ReadError) -> Self {
match e {
ReadError::Generic(ex) => IndexError::Generic(ex),
ReadError::SegmentNotFound => IndexError::IndexNotFound,
ReadError::InvalidPersyId(_) => unreachable!(),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum GenericError {
#[error("IO Error: {from}")]
Io {
from: io::Error,
#[cfg(feature = "unstable")]
backtrace: Backtrace,
},
#[error("String decoding error: {0}")]
DecodingUtf8(#[from] str::Utf8Error),
#[error("Varint Decoding error: {0}")]
VarIntError(#[from] unsigned_varint::io::ReadError),
}
impl From<io::Error> for GenericError {
fn from(err: io::Error) -> Self {
#[cfg(feature = "test_backtraces")]
eprintln!("{:?}", backtrace::Backtrace::new());
GenericError::Io {
from: err,
#[cfg(feature = "unstable")]
backtrace: Backtrace::capture(),
}
}
}
impl From<io::Error> for PersyError {
fn from(err: io::Error) -> Self {
#[cfg(feature = "test_backtraces")]
eprintln!("{:?}", backtrace::Backtrace::new());
PersyError::Io {
from: err,
#[cfg(feature = "unstable")]
backtrace: Backtrace::capture(),
}
}
}
impl From<GenericError> for PersyError {
fn from(e: GenericError) -> Self {
match e {
GenericError::Io {
from,
#[cfg(feature = "unstable")]
backtrace,
} => PersyError::Io {
from,
#[cfg(feature = "unstable")]
backtrace,
},
GenericError::DecodingUtf8(e) => PersyError::DecodingUtf8(e),
GenericError::VarIntError(e) => PersyError::VarIntError(e),
}
}
}
impl From<CreateSegmentError> for PersyError {
fn from(e: CreateSegmentError) -> Self {
match e {
CreateSegmentError::Generic(e) => e.into(),
CreateSegmentError::SegmentAlreadyExists => PersyError::SegmentAlreadyExists,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum DeleteError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("The id '{0}' has no valid format")]
RecordNotFound(PersyId),
#[error("Segment Not Found")]
SegmentNotFound,
#[error("The id '{0}' has no valid format")]
InvalidPersyId(RecRef),
}
impl From<ReadError> for DeleteError {
fn from(e: ReadError) -> Self {
match e {
ReadError::Generic(e) => e.into(),
ReadError::SegmentNotFound => DeleteError::SegmentNotFound,
ReadError::InvalidPersyId(id) => DeleteError::InvalidPersyId(id),
}
}
}
impl From<SegmentError> for DeleteError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(e) => e.into(),
SegmentError::SegmentNotFound => DeleteError::SegmentNotFound,
}
}
}
impl From<DeleteError> for PersyError {
fn from(e: DeleteError) -> Self {
match e {
DeleteError::Generic(e) => e.into(),
DeleteError::RecordNotFound(id) => PersyError::RecordNotFound(id),
DeleteError::SegmentNotFound => PersyError::SegmentNotFound,
DeleteError::InvalidPersyId(id) => PersyError::InvalidPersyId(id),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum UpdateError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("The id '{0}' has no valid format")]
RecordNotFound(PersyId),
#[error("Segment Not Found")]
SegmentNotFound,
#[error("Size of the record is too big")]
RecordToBig,
#[error("The id '{0}' has no valid format")]
InvalidPersyId(RecRef),
}
impl From<SegmentError> for UpdateError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(e) => e.into(),
SegmentError::SegmentNotFound => UpdateError::SegmentNotFound,
}
}
}
impl From<ReadError> for UpdateError {
fn from(e: ReadError) -> Self {
match e {
ReadError::Generic(e) => e.into(),
ReadError::SegmentNotFound => UpdateError::SegmentNotFound,
ReadError::InvalidPersyId(id) => UpdateError::InvalidPersyId(id),
}
}
}
impl From<UpdateError> for PersyError {
fn from(e: UpdateError) -> Self {
match e {
UpdateError::Generic(e) => e.into(),
UpdateError::RecordToBig => PersyError::RecordToBig,
UpdateError::RecordNotFound(id) => PersyError::RecordNotFound(id),
UpdateError::SegmentNotFound => PersyError::SegmentNotFound,
UpdateError::InvalidPersyId(id) => PersyError::InvalidPersyId(id),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum IndexOpsError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Index Not Found")]
IndexNotFound,
#[error("Index method type mismatch persistent types: {0}")]
IndexTypeMismatch(Cow<'static, str>),
}
impl From<IndexOpsError> for PersyError {
fn from(e: IndexOpsError) -> Self {
match e {
IndexOpsError::Generic(e) => e.into(),
IndexOpsError::IndexNotFound => PersyError::SegmentNotFound,
IndexOpsError::IndexTypeMismatch(s) => PersyError::IndexTypeMismatch(s),
}
}
}
impl From<IndexError> for IndexOpsError {
fn from(e: IndexError) -> Self {
match e {
IndexError::Generic(e) => IndexOpsError::Generic(e),
IndexError::IndexNotFound => IndexOpsError::IndexNotFound,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum PrepareError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Index Not Found")]
IndexNotFound,
#[error("Segment Not Found")]
SegmentNotFound,
#[error("Segment Already Exists")]
SegmentAlreadyExists,
#[error("Index Already Exists")]
IndexAlreadyExists,
#[error("Timeout acquiring the data locks for the transaction")]
TransactionTimeout,
#[error("Record Not Found {0}")]
RecordNotFound(PersyId),
#[error("Version Not Latest")]
VersionNotLatest,
#[error("Reached the limit of retry changing the index")]
ReachedLimitOfRetry,
#[error("Found duplicate key:{0} for index: {1}")]
IndexDuplicateKey(String, String),
}
impl From<ReadError> for PrepareError {
fn from(read: ReadError) -> PrepareError {
match read {
ReadError::Generic(e) => PrepareError::Generic(e),
ReadError::SegmentNotFound => PrepareError::SegmentNotFound,
ReadError::InvalidPersyId(_) => panic!("Invalid id should have failed before"),
}
}
}
impl From<TimeoutError> for PrepareError {
fn from(e: TimeoutError) -> Self {
match e {
TimeoutError::LockTimeout => PrepareError::TransactionTimeout,
}
}
}
impl From<PrepareError> for PersyError {
fn from(e: PrepareError) -> Self {
match e {
PrepareError::Generic(ee) => ee.into(),
PrepareError::IndexNotFound => PersyError::IndexNotFound,
PrepareError::SegmentNotFound => PersyError::SegmentNotFound,
PrepareError::SegmentAlreadyExists => PersyError::SegmentAlreadyExists,
PrepareError::IndexAlreadyExists => PersyError::IndexAlreadyExists,
PrepareError::TransactionTimeout => PersyError::TransactionTimeout,
PrepareError::RecordNotFound(id) => PersyError::RecordNotFound(id),
PrepareError::VersionNotLatest => PersyError::VersionNotLatest,
PrepareError::ReachedLimitOfRetry => PersyError::ReachedLimitOfRetry,
PrepareError::IndexDuplicateKey(a, b) => PersyError::IndexDuplicateKey(a, b),
}
}
}
#[derive(Debug, Error)]
pub enum TimeoutError {
#[error("Timeout acquiring the data locks")]
LockTimeout,
}
impl From<TimeoutError> for PersyError {
fn from(e: TimeoutError) -> Self {
match e {
TimeoutError::LockTimeout => PersyError::TransactionTimeout,
}
}
}
pub type PIRes<T> = Result<T, IndexChangeError>;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum IndexChangeError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Timeout acquiring the data locks")]
LockTimeout,
#[error("Reached the limit of retry changing the index")]
ReachedLimitOfRetry,
#[error("Index Not Found")]
IndexNotFound,
#[error("Index method type mismatch persistent types: {0}")]
IndexTypeMismatch(Cow<'static, str>),
#[error("Found duplicate key:{0} for index: {1}")]
IndexDuplicateKey(String, String),
}
impl From<TimeoutError> for IndexChangeError {
fn from(e: TimeoutError) -> Self {
match e {
TimeoutError::LockTimeout => IndexChangeError::LockTimeout,
}
}
}
impl From<IndexOpsError> for IndexChangeError {
fn from(e: IndexOpsError) -> Self {
match e {
IndexOpsError::Generic(ee) => IndexChangeError::Generic(ee),
IndexOpsError::IndexNotFound => IndexChangeError::IndexNotFound,
IndexOpsError::IndexTypeMismatch(s) => IndexChangeError::IndexTypeMismatch(s),
}
}
}
impl From<IndexError> for IndexChangeError {
fn from(e: IndexError) -> Self {
match e {
IndexError::Generic(ee) => IndexChangeError::Generic(ee),
IndexError::IndexNotFound => IndexChangeError::IndexNotFound,
}
}
}
impl From<SegmentError> for IndexChangeError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(ee) => IndexChangeError::Generic(ee),
SegmentError::SegmentNotFound => IndexChangeError::IndexNotFound,
}
}
}
impl From<DeleteError> for IndexChangeError {
fn from(e: DeleteError) -> Self {
match e {
DeleteError::Generic(ee) => IndexChangeError::Generic(ee),
DeleteError::SegmentNotFound => IndexChangeError::IndexNotFound,
DeleteError::RecordNotFound(_) => panic!("Record should be protected by lock while index update"),
DeleteError::InvalidPersyId(_) => panic!("Internally should never get and invalid id"),
}
}
}
impl From<UpdateError> for IndexChangeError {
fn from(e: UpdateError) -> Self {
match e {
UpdateError::Generic(ee) => IndexChangeError::Generic(ee),
UpdateError::SegmentNotFound => IndexChangeError::IndexNotFound,
UpdateError::RecordToBig => panic!("Record size should be limited by key sizes"),
UpdateError::RecordNotFound(_) => panic!("Record should be protected by lock while index update"),
UpdateError::InvalidPersyId(_) => panic!("Internally should never get an invalid id"),
}
}
}
impl From<InsertError> for IndexChangeError {
fn from(e: InsertError) -> Self {
match e {
InsertError::Generic(ee) => IndexChangeError::Generic(ee),
InsertError::SegmentNotFound => IndexChangeError::IndexNotFound,
InsertError::RecordToBig => panic!("Record size should be limited by key sizes"),
}
}
}
impl From<IndexChangeError> for PrepareError {
fn from(e: IndexChangeError) -> Self {
match e {
IndexChangeError::Generic(ee) => PrepareError::Generic(ee),
IndexChangeError::IndexNotFound => PrepareError::IndexNotFound,
IndexChangeError::IndexTypeMismatch(_) => {
panic!("In the prepare context should not be there a index type miss match")
}
IndexChangeError::LockTimeout => PrepareError::TransactionTimeout,
IndexChangeError::ReachedLimitOfRetry => PrepareError::ReachedLimitOfRetry,
IndexChangeError::IndexDuplicateKey(a, b) => PrepareError::IndexDuplicateKey(a, b),
}
}
}
impl From<IndexChangeError> for PersyError {
fn from(e: IndexChangeError) -> Self {
match e {
IndexChangeError::Generic(ee) => ee.into(),
IndexChangeError::IndexNotFound => PersyError::IndexNotFound,
IndexChangeError::IndexTypeMismatch(i) => PersyError::IndexTypeMismatch(i),
IndexChangeError::LockTimeout => PersyError::TransactionTimeout,
IndexChangeError::ReachedLimitOfRetry => PersyError::ReachedLimitOfRetry,
IndexChangeError::IndexDuplicateKey(a, b) => PersyError::IndexDuplicateKey(a, b),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum IndexPutError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Index Not Found")]
IndexNotFound,
#[error("Index method type mismatch persistent types: {0}")]
IndexTypeMismatch(Cow<'static, str>),
#[error("The key or the value are over the allowed size limit")]
KeyOrValueTooBig,
}
impl From<IndexOpsError> for IndexPutError {
fn from(e: IndexOpsError) -> Self {
match e {
IndexOpsError::Generic(ee) => Self::Generic(ee),
IndexOpsError::IndexNotFound => Self::IndexNotFound,
IndexOpsError::IndexTypeMismatch(s) => Self::IndexTypeMismatch(s),
}
}
}
impl From<IndexPutError> for PersyError {
fn from(e: IndexPutError) -> Self {
match e {
IndexPutError::Generic(ee) => ee.into(),
IndexPutError::IndexNotFound => Self::IndexNotFound,
IndexPutError::IndexTypeMismatch(i) => Self::IndexTypeMismatch(i),
IndexPutError::KeyOrValueTooBig => Self::KeyOrValueTooBig,
}
}
}
impl From<IndexError> for IndexPutError {
fn from(e: IndexError) -> Self {
match e {
IndexError::Generic(ee) => Self::Generic(ee),
IndexError::IndexNotFound => Self::IndexNotFound,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum InvalidPersyId {
#[error("String decoding error: {0}")]
DecodingUtf8(#[from] str::Utf8Error),
#[error("Failure acquiring lock for poisoning")]
DecodingDataEncoding(#[from] data_encoding::DecodeError),
#[error("The id '{0}' has no valid format")]
InvalidPersyId(String),
}
impl From<InvalidPersyId> for PersyError {
fn from(e: InvalidPersyId) -> Self {
match e {
InvalidPersyId::InvalidPersyId(id) => PersyError::InvalidId(id),
InvalidPersyId::DecodingUtf8(err) => PersyError::DecodingUtf8(err),
InvalidPersyId::DecodingDataEncoding(err) => PersyError::DecodingDataEncoding(err),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum OpenError {
#[error("Failure acquiring file lock: {0}")]
AlreadyInUse(io::Error),
#[error("File do not exists")]
NotExists,
#[error("Cannot create a new file already exists")]
AlreadyExists,
#[error("The file specified is not a Persy file")]
NotPersyFile,
#[error("{0}")]
InitError(String),
#[error(transparent)]
Generic(#[from] GenericError),
}
impl From<OpenError> for PersyError {
fn from(e: OpenError) -> Self {
match e {
OpenError::AlreadyInUse(err) => PersyError::AlreadyInUse(err),
OpenError::InitError(e) => PersyError::InitError(e),
OpenError::NotExists => PersyError::NotExists,
OpenError::AlreadyExists => PersyError::AlreadyExists,
OpenError::NotPersyFile => PersyError::NotPersyFile,
OpenError::Generic(ge) => ge.into(),
}
}
}
impl From<io::Error> for OpenError {
fn from(err: io::Error) -> Self {
if err.kind() == io::ErrorKind::NotFound {
OpenError::NotExists
} else if err.raw_os_error() == fs2::lock_contended_error().raw_os_error() {
OpenError::AlreadyInUse(err)
} else if err.kind() == io::ErrorKind::AlreadyExists {
OpenError::AlreadyExists
} else {
OpenError::from(GenericError::from(err))
}
}
}
impl From<CreateError> for OpenError {
fn from(e: CreateError) -> Self {
match e {
CreateError::AlreadyInUse(err) => OpenError::AlreadyInUse(err),
CreateError::AlreadyExists => OpenError::AlreadyExists,
CreateError::Generic(ge) => OpenError::Generic(ge),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum OpenMemoryError {
#[error("{0}")]
InitError(String),
#[error(transparent)]
Generic(#[from] GenericError),
}
impl From<OpenMemoryError> for PersyError {
fn from(e: OpenMemoryError) -> Self {
match e {
OpenMemoryError::InitError(e) => PersyError::InitError(e),
OpenMemoryError::Generic(ge) => ge.into(),
}
}
}
impl From<OpenError> for OpenMemoryError {
fn from(e: OpenError) -> Self {
match e {
OpenError::AlreadyInUse(_) => unreachable!(),
OpenError::InitError(ie) => OpenMemoryError::InitError(ie),
OpenError::NotExists => unreachable!(),
OpenError::AlreadyExists => unreachable!(),
OpenError::NotPersyFile => unreachable!(),
OpenError::Generic(ge) => OpenMemoryError::Generic(ge),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CreateError {
#[error("Failure acquiring file lock: {0}")]
AlreadyInUse(io::Error),
#[error("Cannot create a new file already exists")]
AlreadyExists,
#[error(transparent)]
Generic(#[from] GenericError),
}
impl From<CreateError> for PersyError {
fn from(e: CreateError) -> Self {
match e {
CreateError::AlreadyInUse(err) => PersyError::AlreadyInUse(err),
CreateError::AlreadyExists => PersyError::AlreadyExists,
CreateError::Generic(ge) => ge.into(),
}
}
}
impl From<io::Error> for CreateError {
fn from(err: io::Error) -> Self {
if err.raw_os_error() == fs2::lock_contended_error().raw_os_error() {
CreateError::AlreadyInUse(err)
} else if err.kind() == io::ErrorKind::AlreadyExists {
CreateError::AlreadyExists
} else {
CreateError::from(GenericError::from(err))
}
}
}
impl From<OpenError> for CreateError {
fn from(open: OpenError) -> Self {
match open {
OpenError::Generic(g) => g.into(),
OpenError::NotExists => unreachable!(),
OpenError::InitError(_) => unreachable!(),
OpenError::AlreadyInUse(x) => CreateError::AlreadyInUse(x),
OpenError::NotPersyFile => unreachable!(),
OpenError::AlreadyExists => CreateError::AlreadyExists,
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum InsertError {
#[error(transparent)]
Generic(#[from] GenericError),
#[error("Size of the record is too big")]
RecordToBig,
#[error("Segment Not Found")]
SegmentNotFound,
}
impl From<InsertError> for PersyError {
fn from(e: InsertError) -> Self {
match e {
InsertError::RecordToBig => PersyError::RecordToBig,
InsertError::Generic(ge) => ge.into(),
InsertError::SegmentNotFound => PersyError::SegmentNotFound,
}
}
}
impl From<SegmentError> for InsertError {
fn from(e: SegmentError) -> Self {
match e {
SegmentError::Generic(e) => InsertError::Generic(e),
SegmentError::SegmentNotFound => InsertError::SegmentNotFound,
}
}
}