ranges 0.4.0

This crate provides a generic alternative to core/std ranges, set-operations to work with them and a range set that can efficiently store them with the least amount of memory possible.
Documentation
use core::{cmp::Ordering, fmt::Debug, ops::Bound};

use proptest::{
    arbitrary::{any, Arbitrary, StrategyFor},
    strategy::{Map, Strategy},
};

use crate::{Domain, GenericRange};

/// Strategy returned by `Arbitrary` implementation
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>;
}