use std::{fmt, io};
pub use dir::{Dir, DirEntry, Key, VERSIONS};
pub use file::{File, FileVersionRead, FileVersionWrite};
pub use hr_id::Id;
mod dir;
mod file;
pub enum ErrorKind {
NotFound,
Conflict,
IO,
}
impl fmt::Debug for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
Self::NotFound => "not found",
Self::Conflict => "conflict",
Self::IO => "file IO error",
})
}
}
pub struct Error {
kind: ErrorKind,
message: String,
}
impl Error {
pub fn new<I: fmt::Display>(kind: ErrorKind, message: I) -> Self {
Self {
kind,
message: message.to_string(),
}
}
pub fn into_inner(self) -> (ErrorKind, String) {
(self.kind, self.message)
}
}
impl From<hr_id::ParseError> for Error {
fn from(cause: hr_id::ParseError) -> Self {
Self {
kind: ErrorKind::IO,
message: cause.to_string(),
}
}
}
impl From<io::Error> for Error {
fn from(cause: io::Error) -> Self {
let kind = match cause.kind() {
io::ErrorKind::NotFound => ErrorKind::NotFound,
io::ErrorKind::WouldBlock => ErrorKind::Conflict,
_ => ErrorKind::IO,
};
Self {
kind,
message: cause.to_string(),
}
}
}
impl From<txn_lock::Error> for Error {
fn from(cause: txn_lock::Error) -> Self {
Self {
kind: ErrorKind::Conflict,
message: cause.to_string(),
}
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}: {}", self.kind, self.message)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}: {}", self.kind, self.message)
}
}
impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;