use core::{cmp::Ordering, fmt::Debug, ops::Bound};
use proptest::{
arbitrary::{any, Arbitrary, StrategyFor},
strategy::{Map, Strategy},
};
use crate::{Domain, GenericRange};
type GenericRangeStrategy<T> =
Map<(StrategyFor<Bound<T>>, StrategyFor<Bound<T>>), fn((Bound<T>, Bound<T>)) -> GenericRange<T>>;
impl<T: Arbitrary + Debug + Domain + 'static> Arbitrary for GenericRange<T> {
type Parameters = T::Parameters;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(any::<Bound<T>>(), any::<Bound<T>>()).prop_map(|(start, end)| match (&start, &end) {
(&Bound::Unbounded, _) | (_, &Bound::Unbounded) => Self::new_with_bounds(start, end),
(
&(Bound::Included(ref val1) | Bound::Excluded(ref val1)),
&(Bound::Included(ref val2) | Bound::Excluded(ref val2)),
) => match val1.cmp(val2) {
Ordering::Less => Self::new_with_bounds(start, end),
Ordering::Equal | Ordering::Greater => Self::new_with_bounds(end, start),
},
})
}
type Strategy = GenericRangeStrategy<T>;
}