use std::fmt;
use std::io;
use std::path::PathBuf;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
Io(io::Error),
Escape(PathBuf),
InvalidJournalName(String),
InvalidJournalHome(PathBuf),
NonUtf8Path(PathBuf),
Corrupt(String),
Recovery(String),
StaleJournal(PathBuf),
Torn {
cause: String,
rollback: String,
},
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Io(e) => write!(f, "io error: {e}"),
Error::Escape(p) => write!(f, "path escapes the root: {}", p.display()),
Error::InvalidJournalName(name) => write!(
f,
"journal name must be a single path component, got {name:?}"
),
Error::InvalidJournalHome(dir) => write!(
f,
"a journal's home must be an absolute directory, got {}",
dir.display()
),
Error::NonUtf8Path(p) => {
write!(f, "journal cannot encode non-UTF-8 path: {}", p.display())
}
Error::Corrupt(what) => write!(f, "journal is corrupt: {what}"),
Error::Recovery(what) => write!(f, "journal replay: {what}"),
Error::StaleJournal(p) => write!(
f,
"a previous change was interrupted and not yet recovered (found {}); \
recover it first, then retry",
p.display()
),
Error::Torn { cause, rollback } => write!(
f,
"{cause}; and rolling back failed too: {rollback}. \
The tree may be partially written — run recovery."
),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Io(e) => Some(e),
_ => None,
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error::Io(e)
}
}