1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
/// A failure is the reason why some data does not conform to a given Fact
pub type Failure = String;
// ///
// #[derive(Clone, Debug, PartialEq, Eq, derive_more::From)]
// pub enum CheckError {
// Check(Failure),
// Internal(ContrafactError),
// }
/// Errors caused by bugs in Facts, Generators, or contrafact itself
#[derive(Clone, Debug, PartialEq, Eq, derive_more::From)]
pub enum ContrafactError {
// TODO: uncomment if this PR is merged:
// https://github.com/rust-fuzz/arbitrary/pull/153
// UnexpectedError(arbitrary::Error),
/// The only type of error we know about right now
Other(String),
}
/// Alias
pub type ContrafactResult<T> = Result<T, ContrafactError>;
/// Errors which can occur during a `mutate()` call
#[derive(Clone, Debug, derive_more::From)]
pub enum MutationError {
/// When running check, this is a failure which was generated instead of mutating the data
Check(Failure),
/// arbitrary failed to produce new data, which means we can't go on
#[from]
Arbitrary(arbitrary::Error),
/// Contrafact experienced a problem
#[from]
Internal(ContrafactError),
/// There was some other bug in the Fact implementation
User(String),
}
impl PartialEq for MutationError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Check(s), Self::Check(o)) => s == o,
(Self::Arbitrary(s), Self::Arbitrary(o)) => s.to_string() == o.to_string(),
(Self::Internal(s), Self::Internal(o)) => s == o,
(Self::User(s), Self::User(o)) => s == o,
_ => false,
}
}
}
/// Alias
pub type Mutation<T> = Result<T, MutationError>;
/// Adds a helpful method to MutationResults
pub trait MutationExt<T> {
/// Map over only the Failures, leaving other error kinds untouched
fn map_check_err(self, f: impl Fn(Failure) -> Failure) -> Mutation<T>;
}
impl<T> MutationExt<T> for Mutation<T> {
fn map_check_err(self, f: impl Fn(Failure) -> Failure) -> Mutation<T> {
match self {
Err(MutationError::Check(e)) => Err(MutationError::Check(f(e))),
other => other,
}
}
}
// /// Mutation errors must give String reasons for mutation, which can be used to
// /// specify the error when used for a Check
// #[derive(derive_more::Deref, derive_more::From)]
// pub struct Mutation<T>(MutationResult<T>);
// impl<T> Mutation<T> {
// pub fn ok(t: T) -> Self {
// Self(Ok(t))
// }
// pub fn result(self) -> MutationResult<T> {
// self.0
// }
// pub fn check_only(self) -> () {
// todo!()
// }
// }
// impl<T> From<Result<T, CheckError>> for Mutation<T> {
// fn from(res: Result<T, CheckError>) -> Self {
// res.map_err(MutationError::from).into()
// }
// }
// impl<T> From<Result<T, arbitrary::Error>> for Mutation<T> {
// fn from(res: Result<T, arbitrary::Error>) -> Self {
// res.map_err(MutationError::from).into()
// }
// }
// impl<T> From<Result<T, ContrafactError>> for Mutation<T> {
// fn from(res: Result<T, ContrafactError>) -> Self {
// res.map_err(MutationError::from).into()
// }
// }