use crate::*;
#[derive(Debug, Clone, PartialEq, Eq, derive_more::From)]
#[must_use = "Check should be used with either `.unwrap()` or `.result()`"]
pub enum Check {
Failures(Vec<Failure>),
Error(String),
}
impl Check {
pub fn map<F>(self, f: F) -> Self
where
F: FnMut(Failure) -> Failure,
{
match self {
Self::Failures(failures) => Self::Failures(failures.into_iter().map(f).collect()),
e => e,
}
}
pub fn unwrap(self) {
match self {
Self::Failures(failures) => {
if !failures.is_empty() {
if failures.len() == 1 {
panic!("Check failed: {}", failures[0])
} else {
panic!("Check failed: {:#?}", failures)
};
}
}
Self::Error(err) => panic!("Internal contrafact error. Check your Facts! {:?}", err),
}
}
pub fn is_ok(&self) -> bool {
matches!(self, Self::Failures(failures) if failures.is_empty())
}
pub fn is_err(&self) -> bool {
!self.is_ok()
}
pub fn failures(&self) -> Result<&[Failure], ContrafactError> {
match self {
Self::Failures(failures) => Ok(failures.as_ref()),
Self::Error(err) => Err(err.clone().into()),
}
}
pub fn result(self) -> ContrafactResult<std::result::Result<(), Vec<Failure>>> {
match self {
Self::Failures(failures) => {
if failures.is_empty() {
Ok(Ok(()))
} else {
Ok(Err(failures))
}
}
Self::Error(err) => Err(err.into()),
}
}
pub fn result_joined(self) -> ContrafactResult<std::result::Result<(), String>> {
self.result().map(|r| r.map_err(|es| es.join(";")))
}
pub fn check<S: ToString>(ok: bool, err: S) -> Self {
if ok {
Self::pass()
} else {
Self::fail(err)
}
}
pub fn from_mutation<T>(res: Mutation<T>) -> Self {
match res {
Ok(_) => Self::pass(),
Err(MutationError::Check(err)) => Self::fail(err),
Err(MutationError::Arbitrary(err)) => Self::Error(err.to_string()),
Err(MutationError::Internal(err)) => Self::Error(format!("{:?}", err)),
Err(MutationError::User(err)) => Self::Error(format!("{:?}", err)),
}
}
pub fn from_result(res: Result<Vec<Failure>, ContrafactError>) -> Self {
res.map(Self::Failures)
.unwrap_or_else(|e| Self::Error(format!("{:?}", e)))
}
pub fn pass() -> Self {
Self::Failures(Vec::with_capacity(0))
}
pub fn fail<S: ToString>(error: S) -> Self {
Self::Failures(vec![error.to_string()])
}
}