1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
pub use std::fs::OpenOptions;
use std::{borrow::Cow, error, fmt, io, str, sync};

use crate::id::PersyId;

/// Enum of possible errors from Persy
#[derive(Debug)]
pub enum PersyError {
    Io(io::Error),
    DecodingUtf8(str::Utf8Error),
    DecodingDataEncoding(data_encoding::DecodeError),
    Custom(Box<dyn error::Error + Send + Sync + 'static>),
    VersionNotLastest,
    RecordNotFound(PersyId),
    SegmentNotFound,
    SegmentAlreadyExists,
    CannotDropSegmentCreatedInTx,
    Lock,
    IndexMinElementsShouldBeAtLeastDoubleOfMax,
    IndexNotFound,
    IndexTypeMismatch(Cow<'static, str>),
    IndexDuplicateKey(String, String),
    TransactionTimeout,
    InvalidId(String),

    #[doc(hidden)]
    __NonExhausive,
}

pub type PRes<T> = Result<T, PersyError>;

impl<T> From<sync::PoisonError<T>> for PersyError {
    fn from(_: sync::PoisonError<T>) -> PersyError {
        PersyError::Lock
    }
}

impl From<io::Error> for PersyError {
    fn from(err: io::Error) -> PersyError {
        PersyError::Io(err)
    }
}

impl From<str::Utf8Error> for PersyError {
    fn from(err: str::Utf8Error) -> PersyError {
        PersyError::DecodingUtf8(err)
    }
}

impl From<data_encoding::DecodeError> for PersyError {
    fn from(err: data_encoding::DecodeError) -> PersyError {
        PersyError::DecodingDataEncoding(err)
    }
}

impl From<Box<dyn error::Error + Send + Sync + 'static>> for PersyError {
    fn from(err: Box<dyn error::Error + Send + Sync + 'static>) -> PersyError {
        PersyError::Custom(err)
    }
}

impl error::Error for PersyError {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        use PersyError::*;
        match self {
            Io(ref e) => Some(e),
            DecodingUtf8(ref e) => Some(e),
            DecodingDataEncoding(ref e) => Some(e),
            Custom(ref e) => Some(e.as_ref()),
            _ => None,
        }
    }
}

impl fmt::Display for PersyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use PersyError::*;
        match self {
            Io(m) => write!(f, "IO Error: {}", m),
            DecodingUtf8(e) => write!(f, "String decoding error: {}", e),
            DecodingDataEncoding(e) => write!(f, "Data Encoding Decoding error: {}", e),
            Custom(e) => write!(f, "{}", e),
            VersionNotLastest => write!(f, "The record version is not latest"),
            RecordNotFound(r) => write!(f, "Record not found: {}", r),

            SegmentNotFound => write!(f, "Segment not found"),

            SegmentAlreadyExists => write!(f, "Segment already exist"),

            CannotDropSegmentCreatedInTx => {
                write!(f, "Create and drop of a segment in the same transaction is not allowed")
            }

            Lock => write!(f, "Failure acquiring lock for poisoning"),

            IndexMinElementsShouldBeAtLeastDoubleOfMax => write!(
                f,
                "Index min page elements should be maximum half of the maximum elements"
            ),

            IndexNotFound => write!(f, "Index not found"),
            IndexTypeMismatch(m) => write!(f, "Index method type mismatch persistent types: {}", m),

            IndexDuplicateKey(i, k) => write!(f, "Found duplicate key:{} for index: {}", k, i),
            TransactionTimeout => write!(f, "Timeout acquiring the data locks for the transaction"),
            InvalidId(id) => write!(f, "The id '{}' has no valid format", id),

            __NonExhausive => write!(f, "__non-Exhausive"),
        }
    }
}