ranges 0.3.3

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::ops::Not;

use crate::{Domain, Ranges};

impl<T: Domain> Ranges<T> {
    /// Inverts the range set.
    ///
    /// # Examples
    /// Empty set:
    /// ```
    /// use ranges::Ranges;
    ///
    /// assert_eq!(!Ranges::<usize>::new(), Ranges::full());
    /// ```
    /// Single entry:
    /// ```
    /// use ranges::{GenericRange, Ranges};
    ///
    /// let ranges = Ranges::from(0..10);
    /// assert_eq!(
    ///     !ranges,
    ///     vec![GenericRange::new_less_than(0), GenericRange::new_at_least(10)].into()
    /// );
    /// ```
    /// Multiple entries:
    /// ```
    /// use ranges::{GenericRange, Ranges};
    ///
    /// let ranges = Ranges::from(vec![GenericRange::from(0..10), (15..=20).into()]);
    /// assert_eq!(
    ///     !ranges,
    ///     vec![
    ///         GenericRange::new_less_than(0),
    ///         (10..15).into(),
    ///         GenericRange::new_greater_than(20)
    ///     ].into()
    /// );
    /// ```
    #[must_use]
    pub fn invert(self) -> Self {
        Self::full().difference(self)
    }
}

/// This calls [`self.invert()`](#method.invert).
impl<T: Domain> Not for Ranges<T> {
    type Output = Self;

    #[must_use]
    fn not(self) -> Self::Output {
        self.invert()
    }
}

#[cfg(test)]
mod tests {
    use alloc::vec;
    use core::cmp::Ordering;
    use core::ops::RangeBounds;

    use proptest::prelude::*;

    use crate::{GenericRange, Ranges};

    #[test]
    fn empty() {
        assert_eq!(!Ranges::<usize>::new(), Ranges::full());
    }

    #[test]
    fn single_range() {
        let ranges = Ranges::from(0..10);
        assert_eq!(
            !ranges,
            Ranges {
                ranges: vec![GenericRange::new_less_than(0), GenericRange::new_at_least(10)]
            }
        );
    }

    #[test]
    fn two_ranges() {
        let ranges = Ranges::from(vec![GenericRange::from(0..10), (15..=20).into()]);
        assert_eq!(
            !ranges,
            Ranges {
                ranges: vec![
                    GenericRange::new_less_than(0),
                    (10..15).into(),
                    GenericRange::new_greater_than(20)
                ]
            }
        );
    }

    proptest! {
        #[ignore]
        #[test]
        fn sorted_and_disjoint(ranges in any::<Ranges<u8>>()) {
            let result = ranges.invert();
            let sorted_and_disjoint = result.as_slice().windows(2).all(|slice| match slice {
                [left, right] => {
                    GenericRange::cmp_start_start(left.start_bound(), right.start_bound()) == Ordering::Less
                        && GenericRange::cmp_end_start(left.end_bound(), right.start_bound()) == Ordering::Less
                },
                _ => false,
            });

            prop_assert!(sorted_and_disjoint);
        }
    }
}