use std::cmp::PartialEq;
use std::fmt::{self, Debug, Display};
use std::io;
use std::error::Error as StdError;
use super::*;
pub type CacheResult<T, Actual> = Result<T, Error<Actual>>;
#[derive(Debug)]
pub enum Error<Actual> {
CasFailed(Actual),
Unsupported(String),
ReportableBug(String),
Io(io::Error),
Corruption {
at: LogID,
},
#[doc(hidden)]
#[cfg(feature = "failpoints")]
FailPoint,
}
use Error::*;
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) -> 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 Other: From<T>
{
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,
},
}
}
}