use super::conclude::{agreement, ranking};
use super::types::{
CONSERVATION_DISAGREEMENT, Equivalence, IDEMPOTENCE_DISAGREEMENT, MONOTONICITY_DISAGREEMENT,
Measure, Order, ROUNDTRIP_DISAGREEMENT, Road,
};
use crate::report::TrialConclusion;
use core::cmp::Ordering;
#[must_use]
#[track_caller]
pub fn roundtrip<Value, Encoded>(
encode: Road<Value, Encoded>,
decode: Road<Encoded, Value>,
same: Equivalence<Value>,
value: &Value,
) -> TrialConclusion {
let restored = decode(&encode(value));
agreement(same, value, &restored, ROUNDTRIP_DISAGREEMENT)
}
#[must_use]
#[track_caller]
pub fn idempotence<Value>(
subject: Road<Value, Value>,
same: Equivalence<Value>,
value: &Value,
) -> TrialConclusion {
let once = subject(value);
let twice = subject(&once);
agreement(same, &once, &twice, IDEMPOTENCE_DISAGREEMENT)
}
#[must_use]
#[track_caller]
pub fn conservation<Domain, Image, Quantity>(
subject: Road<Domain, Image>,
entering: Measure<Domain, Quantity>,
leaving: Measure<Image, Quantity>,
same: Equivalence<Quantity>,
value: &Domain,
) -> TrialConclusion {
let before = entering(value);
let after = leaving(&subject(value));
agreement(same, &before, &after, CONSERVATION_DISAGREEMENT)
}
#[must_use]
#[track_caller]
pub fn monotonicity<Domain, Image>(
subject: Road<Domain, Image>,
domain_order: Order<Domain>,
image_order: Order<Image>,
left: &Domain,
right: &Domain,
) -> TrialConclusion {
let (lower, upper) = match domain_order(left, right) {
Ordering::Greater => (right, left),
Ordering::Less | Ordering::Equal => (left, right),
};
ranking(
image_order,
&subject(lower),
&subject(upper),
MONOTONICITY_DISAGREEMENT,
)
}