use std::{
cmp::PartialEq,
error::Error as StdError,
fmt::{self, Debug, Display},
io,
};
use super::*;
pub type Result<T, Actual> = std::result::Result<T, Error<Actual>>;
#[derive(Debug)]
pub enum Error<Actual> {
CasFailed(Actual),
Unsupported(String),
ReportableBug(String),
Io(io::Error),
Corruption {
at: DiskPtr,
},
#[doc(hidden)]
#[cfg(feature = "failpoints")]
FailPoint,
}
use self::Error::*;
impl<A> Eq for Error<A> where A: Eq {}
impl<A> PartialEq for Error<A>
where
A: PartialEq,
{
fn eq(&self, other: &Error<A>) -> bool {
match self {
&CasFailed(ref l) => {
if let &CasFailed(ref r) = other {
l == r
} else {
false
}
}
&Unsupported(ref l) => {
if let &Unsupported(ref r) = other {
l == r
} else {
false
}
}
&ReportableBug(ref l) => {
if let &ReportableBug(ref r) = other {
l == r
} else {
false
}
}
#[cfg(feature = "failpoints")]
&FailPoint => if let &FailPoint = other {
true
} else {
false
},
&Corruption { at: l } => {
if let &Corruption { at: r } = other {
l == r
} else {
false
}
}
&Io(_) => false,
}
}
}
impl<T> From<io::Error> for Error<T> {
#[inline]
fn from(io_error: io::Error) -> Error<T> {
Error::Io(io_error)
}
}
impl<T> StdError for Error<T>
where
T: Debug,
{
fn description(&self) -> &str {
match *self {
CasFailed(_) => {
"Compare and swap failed to successfully compare."
}
Unsupported(ref e) => &*e,
ReportableBug(ref e) => &*e,
#[cfg(feature = "failpoints")]
FailPoint => "Fail point has been triggered.",
Io(ref e) => e.description(),
Corruption { .. } => "Read corrupted data.",
}
}
}
impl<A> Display for Error<A>
where
A: Debug,
{
fn fmt(
&self,
f: &mut fmt::Formatter<'_>,
) -> std::result::Result<(), fmt::Error> {
match *self {
CasFailed(ref e) => write!(
f,
"Compare and swap failed to successfully compare \
with actual value {:?}",
e
),
Unsupported(ref e) => write!(f, "Unsupported: {}", e),
ReportableBug(ref e) => write!(
f,
"Unexpected bug has happened: {}. \
PLEASE REPORT THIS BUG!",
e
),
#[cfg(feature = "failpoints")]
FailPoint => write!(f, "Fail point has been triggered."),
Io(ref e) => write!(f, "IO error: {}", e),
Corruption { at } => {
write!(f, "Read corrupted data at file offset {}", at)
}
}
}
}
impl<T> Error<T> {
pub fn danger_cast<Other>(self) -> Error<Other> {
match self {
CasFailed(_) => {
panic!(
"trying to cast CasFailed(()) into a different Error type"
)
}
Unsupported(s) => Unsupported(s),
ReportableBug(s) => ReportableBug(s),
#[cfg(feature = "failpoints")]
FailPoint => FailPoint,
Io(e) => Io(e),
Corruption {
at,
} => Corruption {
at,
},
}
}
pub fn cast<Other>(self) -> Error<Other>
where
T: Into<Other>,
{
match self {
CasFailed(other) => CasFailed(other.into()),
Unsupported(s) => Unsupported(s),
ReportableBug(s) => ReportableBug(s),
#[cfg(feature = "failpoints")]
FailPoint => FailPoint,
Io(e) => Io(e),
Corruption { at } => Corruption { at },
}
}
}