1#![warn(missing_docs)]
108#![forbid(unsafe_code)]
109#![cfg_attr(docsrs, feature(doc_cfg))]
110
111#[cfg(doctest)]
113#[doc = include_str!("../README.md")]
114mod readme {}
115
116#[cfg(feature = "serde")]
117use serde::{Deserialize, Serialize};
118
119use std::ops::{Bound, RangeBounds};
120
121use integer::NumericInteger;
122use range::AnyRange;
123
124pub mod integer;
126pub mod range;
128
129fn range_to_bounds<T: NumericInteger, R: RangeBounds<T>>(range: &R) -> Option<(T, T)> {
130 let min = match range.start_bound() {
131 Bound::Included(t) => *t,
132 Bound::Excluded(t) => {
133 if *t == T::max_value() {
134 return None;
135 }
136 *t + T::one()
137 }
138 Bound::Unbounded => T::min_value(),
139 };
140 let max = match range.end_bound() {
141 Bound::Included(t) => *t,
142 Bound::Excluded(t) => {
143 if *t == T::min_value() {
144 return None;
145 }
146 *t - T::one()
147 }
148 Bound::Unbounded => T::max_value(),
149 };
150
151 if min > max {
152 None
153 } else {
154 Some((min, max))
155 }
156}
157
158#[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
160#[cfg_attr(feature = "serde", derive(Serialize))]
161pub struct RangeSet<T: NumericInteger>(
162 pub Vec<T>,
164);
165
166#[cfg(feature = "serde")]
167#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
168impl<'de, T: NumericInteger + Deserialize<'de>> Deserialize<'de> for RangeSet<T> {
169 fn deserialize<D>(deserializer: D) -> Result<RangeSet<T>, D::Error>
170 where
171 D: serde::Deserializer<'de>,
172 {
173 let bounds = Vec::<T>::deserialize(deserializer)?;
174 RangeSet::new_from_bounds(bounds).ok_or_else(|| {
175 serde::de::Error::custom(
176 "invalid RangeSet: expected an even number of inclusive bounds describing sorted, non-overlapping and non-adjacent ranges",
177 )
178 })
179 }
180}
181
182impl<T: NumericInteger> std::fmt::Display for RangeSet<T> {
183 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
184 write!(f, "[ ")?;
185 for bounds in self.0.chunks_exact(2) {
186 write!(f, "{}..={} ", bounds[0], bounds[1])?;
187 }
188 write!(f, "]")
189 }
190}
191
192#[derive(Clone, Debug)]
197pub struct RangeSetIter<'a, T: NumericInteger> {
198 bounds: &'a [T],
199 front: usize,
201 back: usize,
204 current: Option<(T, T)>,
206 current_back: Option<(T, T)>,
208}
209
210impl<T: NumericInteger> Iterator for RangeSetIter<'_, T> {
211 type Item = T;
212
213 fn next(&mut self) -> Option<Self::Item> {
214 if let Some((min, max)) = self.current {
216 self.current = if min < max {
217 Some((min + T::one(), max))
218 } else {
219 None
220 };
221 return Some(min);
222 }
223
224 if self.front < self.back {
227 let (min, max) = (self.bounds[self.front], self.bounds[self.front + 1]);
228 self.front += 2;
229 if min < max {
230 self.current = Some((min + T::one(), max));
231 }
232 return Some(min);
233 }
234
235 let (min, max) = self.current_back?;
237 self.current_back = if min < max {
238 Some((min + T::one(), max))
239 } else {
240 None
241 };
242 Some(min)
243 }
244}
245
246impl<T: NumericInteger> DoubleEndedIterator for RangeSetIter<'_, T> {
247 fn next_back(&mut self) -> Option<Self::Item> {
248 if let Some((min, max)) = self.current_back {
250 self.current_back = if min < max {
251 Some((min, max - T::one()))
252 } else {
253 None
254 };
255 return Some(max);
256 }
257
258 if self.front < self.back {
260 let (min, max) = (self.bounds[self.back - 2], self.bounds[self.back - 1]);
261 self.back -= 2;
262 if min > max {
264 return Some(min);
265 }
266 if min < max {
267 self.current_back = Some((min, max - T::one()));
268 }
269 return Some(max);
270 }
271
272 let (min, max) = self.current?;
274 self.current = if min < max {
275 Some((min, max - T::one()))
276 } else {
277 None
278 };
279 Some(max)
280 }
281}
282
283impl<T: NumericInteger> std::iter::FusedIterator for RangeSetIter<'_, T> {}
284
285impl<T: NumericInteger> RangeSet<T> {
286 pub fn iter(&self) -> RangeSetIter<'_, T> {
300 let len = self.0.len();
303 RangeSetIter {
304 bounds: &self.0,
305 front: 0,
306 back: len - len % 2,
307 current: None,
308 current_back: None,
309 }
310 }
311
312 pub fn new_from_range<R: RangeBounds<T>>(range: R) -> RangeSet<T> {
329 match range_to_bounds(&range) {
330 Some((min, max)) => RangeSet(vec![min, max]),
331 None => RangeSet::empty(),
332 }
333 }
334
335 pub fn new_from_ranges(ranges: &[AnyRange<T>]) -> RangeSet<T> {
347 let mut ranges: Vec<(T, T)> = ranges
348 .iter()
349 .map(|range| range.get_bounds())
350 .filter(|(min, max)| max >= min)
351 .copied()
352 .collect();
353 let mut is_sorted = true;
355 if let Some((first_min, _)) = ranges.first() {
356 let mut previous_min = *first_min;
357 for (min, _) in &ranges[1..] {
358 if *min < previous_min {
359 is_sorted = false;
360 break;
361 }
362 previous_min = *min;
363 }
364 }
365 if !is_sorted {
366 ranges.sort_by_key(|range| range.0);
367 }
368
369 let mut bounds = Vec::with_capacity(ranges.len() * 2);
370 let mut current_max = T::min_value();
371 for (min, max) in ranges {
372 if bounds.is_empty() || (current_max < T::max_value() && min > current_max + T::one()) {
373 bounds.extend_from_slice(&[min, max]);
374 current_max = max;
375 } else if max > current_max {
376 *bounds.last_mut().unwrap() = max;
377 current_max = max;
378 }
379 }
380
381 bounds.shrink_to_fit();
382 RangeSet(bounds)
383 }
384
385 pub fn new_from_bounds(bounds: Vec<T>) -> Option<RangeSet<T>> {
405 if bounds.len() % 2 == 1 {
406 return None;
407 }
408
409 let mut previous_max: Option<T> = None;
410 for range in bounds.chunks_exact(2) {
411 let (min, max) = (range[0], range[1]);
412 if min > max {
413 return None;
414 }
415 if let Some(previous_max) = previous_max {
416 if previous_max >= T::max_value() || min <= previous_max + T::one() {
418 return None;
419 }
420 }
421 previous_max = Some(max);
422 }
423
424 Some(RangeSet(bounds))
425 }
426
427 #[inline]
438 pub fn empty() -> RangeSet<T> {
439 RangeSet(vec![])
440 }
441
442 #[inline]
458 pub fn total() -> RangeSet<T> {
459 RangeSet(vec![T::min_value(), T::max_value()])
460 }
461
462 #[inline]
476 pub fn is_total(&self) -> bool {
477 self.0.len() >= 2 && self.0[0] == T::min_value() && self.0[1] >= T::max_value()
478 }
479
480 #[inline]
494 pub fn is_empty(&self) -> bool {
495 self.0.is_empty()
496 }
497
498 pub fn contains(&self, value: T) -> bool {
511 if self.is_empty() {
512 return false;
513 }
514 let first = *self.0.first().unwrap();
515 let last = *self.0.last().unwrap();
516 if value < first || value > last {
517 return false;
518 } else if value == first || value == last {
519 return true;
520 }
521
522 let position = self.0.partition_point(|&x| x < value);
523
524 self.0[position] == value || position % 2 != 0
525 }
526
527 pub fn contains_all(&self, that: &RangeSet<T>) -> bool {
541 if self.is_total() || that.is_empty() {
542 return true;
543 }
544 if self.is_empty() || that.is_total() {
545 return false;
546 }
547
548 if that.0[0] < self.0[0] || that.0[that.0.len() - 1] > self.0[self.0.len() - 1] {
550 return false;
551 }
552
553 let mut self_i = 0;
554
555 for bounds in that.0.chunks_exact(2) {
556 let (that_min, that_max) = (bounds[0], bounds[1]);
557
558 while self_i + 1 < self.0.len() && self.0[self_i + 1] < that_min {
560 self_i += 2;
561 }
562
563 if self_i + 1 >= self.0.len()
564 || self.0[self_i] > that_min
565 || self.0[self_i + 1] < that_max
566 {
567 return false;
568 }
569 }
570 true
571 }
572
573 pub fn union(&self, that: &RangeSet<T>) -> RangeSet<T> {
587 if self.is_empty() || that.is_total() {
588 return that.clone();
589 } else if that.is_empty() || self.is_total() {
590 return self.clone();
591 }
592
593 let mut new_range = Vec::with_capacity(self.0.len() + that.0.len());
594
595 let mut self_i = 0;
596 let mut that_i = 0;
597
598 let mut current: Option<(T, T)> = None;
601
602 while self_i + 1 < self.0.len() || that_i + 1 < that.0.len() {
603 let (min, max) = if that_i + 1 < that.0.len()
605 && (self_i + 1 >= self.0.len() || self.0[self_i] > that.0[that_i])
606 {
607 that_i += 2;
608 (that.0[that_i - 2], that.0[that_i - 1])
609 } else {
610 self_i += 2;
611 (self.0[self_i - 2], self.0[self_i - 1])
612 };
613
614 match current {
615 Some((current_min, current_max))
617 if min <= current_max
618 || (current_max < T::max_value() && min <= current_max + T::one()) =>
619 {
620 if max > current_max {
621 current = Some((current_min, max));
622 }
623 }
624 Some((current_min, current_max)) => {
625 new_range.extend_from_slice(&[current_min, current_max]);
626 current = Some((min, max));
627 }
628 None => current = Some((min, max)),
629 }
630 }
631
632 if let Some((current_min, current_max)) = current {
633 new_range.extend_from_slice(&[current_min, current_max]);
634 }
635
636 new_range.shrink_to_fit();
637 RangeSet(new_range)
638 }
639
640 pub fn has_intersection(&self, that: &RangeSet<T>) -> bool {
656 let mut i = 0;
657 let mut j = 0;
658
659 while i + 1 < self.0.len() && j + 1 < that.0.len() {
660 let self_min = self.0[i];
661 let self_max = self.0[i + 1];
662 let that_min = that.0[j];
663 let that_max = that.0[j + 1];
664
665 if self_max < that_min {
666 i += 2;
667 } else if that_max < self_min {
668 j += 2;
669 } else {
670 return true;
671 }
672 }
673
674 false
675 }
676
677 pub fn intersection(&self, that: &RangeSet<T>) -> RangeSet<T> {
691 if self.is_empty() || that.is_empty() {
692 return RangeSet::empty();
693 } else if self.is_total() {
694 return that.clone();
695 } else if that.is_total() {
696 return self.clone();
697 }
698
699 let mut new_range = Vec::with_capacity(self.0.len() + that.0.len());
700
701 let mut i = 0;
702 let mut j = 0;
703
704 while i + 1 < self.0.len() && j + 1 < that.0.len() {
705 let self_min = self.0[i];
706 let self_max = self.0[i + 1];
707 let that_min = that.0[j];
708 let that_max = that.0[j + 1];
709
710 if self_max < that_min {
711 i += 2;
712 } else if that_max < self_min {
713 j += 2;
714 } else {
715 new_range.push(std::cmp::max(self_min, that_min));
716 new_range.push(std::cmp::min(self_max, that_max));
717
718 if self_max < that_max {
719 i += 2;
720 } else {
721 j += 2;
722 }
723 }
724 }
725
726 new_range.shrink_to_fit();
727 RangeSet(new_range)
728 }
729
730 pub fn complement(&self) -> RangeSet<T> {
743 if self.is_empty() {
744 return Self::total();
745 } else if self.is_total() {
746 return Self::empty();
747 }
748
749 let mut new_range = Vec::with_capacity(self.0.len() + 2);
750
751 let first = self.0[0];
755 if first > T::min_value() {
756 new_range.extend_from_slice(&[T::min_value(), first - T::one()]);
757 }
758
759 let inner = if self.0.len() > 2 {
762 &self.0[1..self.0.len() - 1]
763 } else {
764 &[][..]
765 };
766 for gap in inner.chunks_exact(2) {
767 let (previous_max, next_min) = (gap[0], gap[1]);
768 if previous_max < T::max_value() && next_min > T::min_value() {
771 let (min, max) = (previous_max + T::one(), next_min - T::one());
772 if min <= max {
773 new_range.extend_from_slice(&[min, max]);
774 }
775 }
776 }
777
778 let last = self.0[self.0.len() - 1];
779 if last < T::max_value() {
780 new_range.extend_from_slice(&[last + T::one(), T::max_value()]);
781 }
782
783 new_range.shrink_to_fit();
784 RangeSet(new_range)
785 }
786
787 pub fn difference(&self, that: &RangeSet<T>) -> RangeSet<T> {
801 if self.is_empty() || that.is_empty() {
802 return self.clone();
803 } else if that.is_total() {
804 return RangeSet::empty();
805 } else if self.is_total() {
806 return that.complement();
807 }
808
809 let mut new_range = Vec::with_capacity(self.0.len() + that.0.len());
813
814 let mut that_i = 0;
816
817 for bounds in self.0.chunks_exact(2) {
818 let (mut min, max) = (bounds[0], bounds[1]);
819
820 while that_i + 1 < that.0.len() && that.0[that_i + 1] < min {
823 that_i += 2;
824 }
825
826 let mut j = that_i;
827 let mut covered = false;
828 while j + 1 < that.0.len() {
829 let (that_min, that_max) = (that.0[j], that.0[j + 1]);
830 if that_min > max {
831 break;
832 }
833
834 if that_min > min {
836 new_range.extend_from_slice(&[min, that_min - T::one()]);
837 }
838 if that_max >= max {
839 covered = true;
840 break;
841 }
842 min = that_max + T::one();
844 j += 2;
845 }
846
847 if !covered {
849 new_range.extend_from_slice(&[min, max]);
850 }
851 }
852
853 new_range.shrink_to_fit();
854 RangeSet(new_range)
855 }
856}
857
858impl<T: NumericInteger> Default for RangeSet<T> {
859 #[inline]
861 fn default() -> RangeSet<T> {
862 RangeSet::empty()
863 }
864}
865
866impl<'a, T: NumericInteger> IntoIterator for &'a RangeSet<T> {
867 type Item = T;
868 type IntoIter = RangeSetIter<'a, T>;
869
870 #[inline]
884 fn into_iter(self) -> RangeSetIter<'a, T> {
885 self.iter()
886 }
887}
888
889impl<T: NumericInteger> FromIterator<AnyRange<T>> for RangeSet<T> {
890 fn from_iter<I: IntoIterator<Item = AnyRange<T>>>(iter: I) -> RangeSet<T> {
902 RangeSet::new_from_ranges(&iter.into_iter().collect::<Vec<_>>())
903 }
904}
905
906impl<T: NumericInteger> std::ops::BitOr<&RangeSet<T>> for &RangeSet<T> {
907 type Output = RangeSet<T>;
908
909 #[inline]
921 fn bitor(self, that: &RangeSet<T>) -> RangeSet<T> {
922 self.union(that)
923 }
924}
925
926impl<T: NumericInteger> std::ops::BitAnd<&RangeSet<T>> for &RangeSet<T> {
927 type Output = RangeSet<T>;
928
929 #[inline]
941 fn bitand(self, that: &RangeSet<T>) -> RangeSet<T> {
942 self.intersection(that)
943 }
944}
945
946impl<T: NumericInteger> std::ops::Sub<&RangeSet<T>> for &RangeSet<T> {
947 type Output = RangeSet<T>;
948
949 #[inline]
961 fn sub(self, that: &RangeSet<T>) -> RangeSet<T> {
962 self.difference(that)
963 }
964}
965
966impl<T: NumericInteger> std::ops::Not for &RangeSet<T> {
967 type Output = RangeSet<T>;
968
969 #[inline]
980 fn not(self) -> RangeSet<T> {
981 self.complement()
982 }
983}
984
985#[cfg(test)]
986mod tests {
987 use std::collections::{BTreeSet, HashSet};
988
989 use super::*;
990
991 macro_rules! test_empty_and_total_for_types {
992 ($($t:ty),*) => {
993 $(
994 let empty = RangeSet::<$t>::empty();
995 assert!(empty.is_empty());
996 assert!(!empty.is_total());
997
998 let total = RangeSet::<$t>::total();
999 assert!(!total.is_empty());
1000 assert!(total.is_total());
1001 )*
1002 };
1003 }
1004
1005 #[test]
1006 fn test_empty_and_total() -> Result<(), String> {
1007 test_empty_and_total_for_types!(
1008 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
1009 );
1010
1011 Ok(())
1012 }
1013
1014 #[test]
1015 fn test_new_from_range() -> Result<(), String> {
1016 assert_eq!(
1017 RangeSet::<u8>(vec![3, 4]),
1018 RangeSet::<u8>::new_from_range(3..5)
1019 );
1020
1021 assert_eq!(
1022 RangeSet::<u8>(vec![3, 5]),
1023 RangeSet::<u8>::new_from_range(3..=5)
1024 );
1025
1026 assert_eq!(
1027 RangeSet::<u8>(vec![0, 5]),
1028 RangeSet::<u8>::new_from_range(..=5)
1029 );
1030
1031 assert_eq!(
1032 RangeSet::<u8>(vec![2, 255]),
1033 RangeSet::<u8>::new_from_range(2..)
1034 );
1035
1036 assert_eq!(
1037 RangeSet::<u8>(vec![0, 255]),
1038 RangeSet::<u8>::new_from_range(..)
1039 );
1040
1041 Ok(())
1042 }
1043
1044 #[test]
1045 #[allow(clippy::reversed_empty_ranges)] fn test_new_from_ranges() -> Result<(), String> {
1047 assert_eq!(
1048 RangeSet(vec![3, 5, 9, 14]),
1049 RangeSet::new_from_ranges(&[AnyRange::from(3..=5), AnyRange::from(9..15)])
1050 );
1051
1052 assert_eq!(
1053 RangeSet(vec![3, 5, 9, 14]),
1054 RangeSet::new_from_ranges(&[AnyRange::from(9..15), AnyRange::from(3..=5)])
1055 );
1056
1057 assert_eq!(
1058 RangeSet(vec![3, 5, 9, 14]),
1059 RangeSet::new_from_ranges(&[
1060 AnyRange::from(9..15),
1061 AnyRange::from(23..18),
1062 AnyRange::from(3..=5),
1063 AnyRange::from(4..=4)
1064 ])
1065 );
1066
1067 assert_eq!(
1068 RangeSet(vec![3, 5, 9, 14]),
1069 RangeSet::new_from_ranges(&[
1070 AnyRange::from(9..15),
1071 AnyRange::from(23..18),
1072 AnyRange::from(3..=5)
1073 ])
1074 );
1075
1076 assert_eq!(
1077 RangeSet(vec![3, 255]),
1078 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(4..), AnyRange::from(3..=5)])
1079 );
1080
1081 assert_eq!(
1082 RangeSet(vec![0, 5]),
1083 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(..=4), AnyRange::from(3..=5)])
1084 );
1085
1086 assert_eq!(
1087 RangeSet::total(),
1088 RangeSet::new_from_ranges(&[AnyRange::from(..), AnyRange::from(3..=5)])
1089 );
1090
1091 assert_eq!(
1092 RangeSet::empty(),
1093 RangeSet::new_from_ranges(&[AnyRange::from(3..1), AnyRange::from(10..=5)])
1094 );
1095
1096 Ok(())
1097 }
1098
1099 #[test]
1100 fn test_contains_all() -> Result<(), String> {
1101 assert!(RangeSet::<u8>::empty().contains_all(&RangeSet::empty()));
1102 assert!(RangeSet::<u8>::total().contains_all(&RangeSet::empty()));
1103 assert!(!RangeSet::<u8>::empty().contains_all(&RangeSet::total()));
1104
1105 assert!(!RangeSet(vec![2, 44]).contains_all(&RangeSet(vec![56, 60])));
1106 assert!(!RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![2, 44])));
1107 assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![56, 60])));
1108 assert!(RangeSet(vec![56, 61]).contains_all(&RangeSet(vec![56, 61])));
1109 assert!(RangeSet(vec![55, 61]).contains_all(&RangeSet(vec![56, 60])));
1110
1111 assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![57, 59])));
1112 assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![57, 60])));
1113 assert!(RangeSet(vec![56, 60]).contains_all(&RangeSet(vec![56, 59])));
1114
1115 assert!(RangeSet(vec![19, 33]).contains_all(&RangeSet(vec![20, 21, 30, 32])));
1116 assert!(
1117 RangeSet(vec![19, 33, 53, 70]).contains_all(&RangeSet(vec![20, 21, 30, 32, 66, 69]))
1118 );
1119 assert!(
1120 !RangeSet(vec![19, 33, 53, 70]).contains_all(&RangeSet(vec![20, 21, 30, 32, 66, 71]))
1121 );
1122
1123 Ok(())
1124 }
1125
1126 #[test]
1127 fn test_iter_and_contains() -> Result<(), String> {
1128 let empty = RangeSet::<u8>::empty();
1129 assert_eq!(0, empty.iter().count());
1130 assert!(!empty.contains(0));
1131
1132 let total = RangeSet::<u8>::total();
1133 assert_eq!(256, total.iter().collect::<HashSet<_>>().len());
1134 assert!(total.iter().all(|v| total.contains(v)));
1135
1136 let range = RangeSet(vec![19, 33, 53, 70]);
1137 assert_eq!(33, range.iter().collect::<HashSet<_>>().len()); assert!(range.iter().all(|v| range.contains(v)));
1139 assert!(!range.contains(34));
1140
1141 Ok(())
1142 }
1143
1144 #[test]
1145 fn test_union() -> Result<(), String> {
1146 assert!(RangeSet::<u8>::empty().union(&RangeSet::empty()).is_empty());
1147 assert!(RangeSet::<u8>::total().union(&RangeSet::empty()).is_total());
1148 assert!(RangeSet::<u8>::empty().union(&RangeSet::total()).is_total());
1149
1150 assert_eq!(
1151 vec![2, 44, 56, 60],
1152 RangeSet(vec![2, 44]).union(&RangeSet(vec![56, 60])).0
1153 );
1154
1155 assert_eq!(
1156 vec![0, 44],
1157 RangeSet(vec![2, 44]).union(&RangeSet(vec![0, 3])).0
1158 );
1159
1160 assert_eq!(
1161 vec![2, 48],
1162 RangeSet(vec![2, 44]).union(&RangeSet(vec![5, 48])).0
1163 );
1164
1165 assert_eq!(
1166 vec![2, 44],
1167 RangeSet(vec![2, 44]).union(&RangeSet(vec![2, 44])).0
1168 );
1169
1170 assert_eq!(
1171 vec![2, 44],
1172 RangeSet(vec![2, 44]).union(&RangeSet(vec![5, 20])).0
1173 );
1174
1175 assert_eq!(
1176 vec![2, 50],
1177 RangeSet(vec![2, 44]).union(&RangeSet(vec![45, 50])).0
1178 );
1179
1180 assert_eq!(
1181 vec![2, 44],
1182 RangeSet(vec![2, 44])
1183 .union(&RangeSet(vec![5, 20, 23, 40, 42, 43]))
1184 .0
1185 );
1186
1187 assert_eq!(
1188 vec![1, 44],
1189 RangeSet(vec![2, 44]).union(&RangeSet(vec![1, 2, 4, 5])).0
1190 );
1191
1192 assert_eq!(
1193 vec![0, 9, 11, 97],
1194 RangeSet(vec![0, 9, 11, 96])
1195 .union(&RangeSet(vec![97, 97]))
1196 .0
1197 );
1198
1199 let range1 = RangeSet::new_from_ranges(&[
1200 AnyRange::from(..=12),
1201 AnyRange::from(15..=15),
1202 AnyRange::from(18..),
1203 ]);
1204 let range2 = RangeSet::new_from_ranges(&[AnyRange::from(..=12), AnyRange::from(15..)]);
1205
1206 let range3 = RangeSet::new_from_ranges(&[AnyRange::from(..=12), AnyRange::from(15..)]);
1207 assert_eq!(range3, range1.union(&range2));
1208
1209 Ok(())
1210 }
1211
1212 #[test]
1213 fn test_intersection() -> Result<(), String> {
1214 assert!(RangeSet::<u32>::empty()
1215 .intersection(&RangeSet::empty())
1216 .is_empty());
1217 assert!(RangeSet::<u32>::total()
1218 .intersection(&RangeSet::empty())
1219 .is_empty());
1220 assert!(RangeSet::<u32>::empty()
1221 .intersection(&RangeSet::total())
1222 .is_empty());
1223 assert!(RangeSet::<u32>::total()
1224 .intersection(&RangeSet::total())
1225 .is_total());
1226
1227 assert_eq!(
1228 RangeSet::empty(),
1229 RangeSet(vec![2, 44]).intersection(&RangeSet(vec![56, 60]))
1230 );
1231
1232 assert_eq!(
1233 vec![2, 3],
1234 RangeSet(vec![2, 44]).intersection(&RangeSet(vec![0, 3])).0
1235 );
1236
1237 assert_eq!(
1238 vec![5, 44],
1239 RangeSet(vec![2, 44]).intersection(&RangeSet(vec![5, 48])).0
1240 );
1241
1242 assert_eq!(
1243 vec![2, 44],
1244 RangeSet(vec![2, 44]).intersection(&RangeSet(vec![2, 44])).0
1245 );
1246
1247 assert_eq!(
1248 vec![5, 20],
1249 RangeSet(vec![2, 44]).intersection(&RangeSet(vec![5, 20])).0
1250 );
1251 assert_eq!(
1252 vec![5, 20, 23, 40],
1253 RangeSet(vec![2, 44])
1254 .intersection(&RangeSet(vec![5, 20, 23, 40]))
1255 .0
1256 );
1257
1258 assert_eq!(
1259 vec![5, 20, 23, 40],
1260 RangeSet(vec![5, 20, 23, 40])
1261 .intersection(&RangeSet(vec![2, 44]))
1262 .0
1263 );
1264
1265 assert!(RangeSet(vec![99, 99])
1266 .intersection(&RangeSet(vec![i32::MIN, 98, 100, i32::MAX]))
1267 .is_empty());
1268 Ok(())
1269 }
1270
1271 #[test]
1272 fn test_complement() -> Result<(), String> {
1273 assert!(RangeSet::<u32>::total().complement().is_empty());
1274 assert!(RangeSet::<u32>::empty().complement().is_total());
1275
1276 assert_eq!(
1277 vec![0, 1, 45, u32::MAX],
1278 RangeSet(vec![2, 44]).complement().0
1279 );
1280
1281 assert_eq!(
1282 vec![45, i64::MAX],
1283 RangeSet(vec![i64::MIN, 44]).complement().0
1284 );
1285
1286 assert_eq!(
1287 vec![45, 238],
1288 RangeSet(vec![0, 44, 239, u32::MAX]).complement().0
1289 );
1290
1291 Ok(())
1292 }
1293
1294 #[cfg(feature = "serde")]
1295 macro_rules! serde_test {
1296 ($($t:ty),*) => {
1297 $(
1298 let range = RangeSet::<$t>::empty();
1299 let serialized = serde_json::to_string(&range).unwrap();
1300 let unserialized: RangeSet<$t> = serde_json::from_str(&serialized).unwrap();
1301 assert_eq!(range, unserialized);
1302
1303 let range = RangeSet::<$t>::total();
1304 let serialized = serde_json::to_string(&range).unwrap();
1305 let unserialized: RangeSet<$t> = serde_json::from_str(&serialized).unwrap();
1306 assert_eq!(range, unserialized);
1307
1308 let range =
1309 RangeSet::<$t>::new_from_ranges(&[AnyRange::from(3..=4), AnyRange::from(7..9)]);
1310 let serialized = serde_json::to_string(&range).unwrap();
1311 let unserialized: RangeSet<$t> = serde_json::from_str(&serialized).unwrap();
1312 assert_eq!(range, unserialized);
1313 )*
1314 };
1315 }
1316
1317 #[test]
1318 #[cfg(feature = "serde")]
1319 fn serde_test() {
1320 serde_test!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
1321 }
1322
1323 struct ExcludedMaxStart;
1325 impl RangeBounds<u8> for ExcludedMaxStart {
1326 fn start_bound(&self) -> Bound<&u8> {
1327 Bound::Excluded(&u8::MAX)
1328 }
1329 fn end_bound(&self) -> Bound<&u8> {
1330 Bound::Unbounded
1331 }
1332 }
1333
1334 struct ExcludedBothEnds(u8, u8);
1336 impl RangeBounds<u8> for ExcludedBothEnds {
1337 fn start_bound(&self) -> Bound<&u8> {
1338 Bound::Excluded(&self.0)
1339 }
1340 fn end_bound(&self) -> Bound<&u8> {
1341 Bound::Excluded(&self.1)
1342 }
1343 }
1344
1345 fn range_set_from_values(values: &[u8]) -> RangeSet<u8> {
1346 RangeSet::new_from_ranges(
1347 &values
1348 .iter()
1349 .map(|&value| AnyRange::from(value..=value))
1350 .collect::<Vec<_>>(),
1351 )
1352 }
1353
1354 fn assert_canonical(range: &RangeSet<u8>) {
1357 assert_eq!(
1358 0,
1359 range.0.len() % 2,
1360 "odd number of bounds in {:?}",
1361 range.0
1362 );
1363 for bounds in range.0.chunks(2) {
1364 assert!(
1365 bounds[0] <= bounds[1],
1366 "inverted range {}..={} in {:?}",
1367 bounds[0],
1368 bounds[1],
1369 range.0
1370 );
1371 }
1372 for pair in range.0.chunks(2).collect::<Vec<_>>().windows(2) {
1373 assert!(
1374 u16::from(pair[1][0]) > u16::from(pair[0][1]) + 1,
1375 "ranges {}..={} and {}..={} should have been merged in {:?}",
1376 pair[0][0],
1377 pair[0][1],
1378 pair[1][0],
1379 pair[1][1],
1380 range.0
1381 );
1382 }
1383 }
1384
1385 #[test]
1386 fn test_new_from_ranges_merges_adjacent_ranges() -> Result<(), String> {
1387 assert_eq!(
1388 RangeSet::<u8>::new_from_range(1..=4),
1389 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(1..=2), AnyRange::from(3..=4)])
1390 );
1391
1392 assert_eq!(
1393 vec![1, 4],
1394 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(3..=4), AnyRange::from(1..=2)]).0
1395 );
1396
1397 assert_eq!(
1399 vec![0, 9],
1400 RangeSet::<u8>::new_from_ranges(&[
1401 AnyRange::from(0..=2),
1402 AnyRange::from(3..=3),
1403 AnyRange::from(4..8),
1404 AnyRange::from(8..=9)
1405 ])
1406 .0
1407 );
1408
1409 assert_eq!(
1411 vec![0, 9],
1412 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..=9), AnyRange::from(3..=4)]).0
1413 );
1414
1415 assert_eq!(
1417 vec![0, 2, 4, 9],
1418 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..=2), AnyRange::from(4..=9)]).0
1419 );
1420
1421 assert_eq!(
1423 vec![250, 255],
1424 RangeSet::<u8>::new_from_ranges(&[
1425 AnyRange::from(250..=254),
1426 AnyRange::from(255..=255)
1427 ])
1428 .0
1429 );
1430 assert!(
1431 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(..), AnyRange::from(200..=255)])
1432 .is_total()
1433 );
1434
1435 Ok(())
1436 }
1437
1438 #[test]
1439 fn test_complement_and_difference_with_adjacent_ranges() -> Result<(), String> {
1440 let range =
1441 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(1..=2), AnyRange::from(3..=4)]);
1442 assert_canonical(&range);
1443
1444 let complement = range.complement();
1445 assert_canonical(&complement);
1446 assert_eq!(vec![0, 0, 5, 255], complement.0);
1447
1448 let range1 = RangeSet::<u8>::new_from_range(9..=12);
1449 let range2 =
1450 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(11..=11), AnyRange::from(12..=17)]);
1451 let difference = range1.difference(&range2);
1452 assert_canonical(&difference);
1453 assert_eq!(vec![9, 10], difference.0);
1454
1455 let range =
1456 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(3..=6), AnyRange::from(7..=11)]);
1457 assert!(range.contains_all(&RangeSet::new_from_range(3..=8)));
1458 assert!(range.contains_all(&RangeSet::new_from_range(3..=11)));
1459 assert!(!range.contains_all(&RangeSet::new_from_range(3..=12)));
1460
1461 Ok(())
1462 }
1463
1464 #[test]
1465 fn test_new_from_empty_range() -> Result<(), String> {
1466 assert!(RangeSet::<u8>::new_from_range(5..5).is_empty());
1467 assert!(RangeSet::<u8>::new_from_range(0..0).is_empty());
1468 assert!(RangeSet::<u8>::new_from_range(..0).is_empty());
1469 assert!(RangeSet::<u8>::new_from_range(ExcludedMaxStart).is_empty());
1470 assert!(RangeSet::<i32>::new_from_range(i32::MIN..i32::MIN).is_empty());
1471 assert!(RangeSet::<i8>::new_from_range(..i8::MIN).is_empty());
1472 assert!(RangeSet::<usize>::new_from_range(0..0).is_empty());
1473
1474 assert!(!RangeSet::<u8>::new_from_range(0..0).is_total());
1476 assert!(!RangeSet::<i32>::new_from_range(i32::MIN..i32::MIN).is_total());
1477
1478 assert!(RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..0)]).is_empty());
1480 assert_eq!(
1481 RangeSet::<u8>::new_from_range(7..=9),
1482 RangeSet::<u8>::new_from_ranges(&[AnyRange::from(0..0), AnyRange::from(7..=9)])
1483 );
1484
1485 assert_eq!(
1487 vec![4, 6],
1488 RangeSet::<u8>::new_from_range(ExcludedBothEnds(3, 7)).0
1489 );
1490 assert_eq!(vec![0, 254], RangeSet::<u8>::new_from_range(..u8::MAX).0);
1491
1492 Ok(())
1493 }
1494
1495 #[test]
1496 fn test_malformed_range_set_does_not_panic() -> Result<(), String> {
1497 for bounds in [
1500 vec![0u8],
1501 vec![1, 5, 9],
1502 vec![5, 3],
1503 vec![10, 20, 0, 5],
1504 vec![1, 255, 3, 5],
1507 vec![255, 0],
1508 vec![0, 0, 255, 255],
1509 vec![255, 255, 0, 0],
1510 ] {
1511 let malformed = RangeSet::<u8>(bounds);
1512 let _ = malformed.is_total();
1513 let _ = malformed.is_empty();
1514 let _ = format!("{malformed}");
1515 let _ = malformed.contains(4);
1516 let _ = malformed.iter().take(512).count();
1517 let _ = malformed.complement();
1518 let _ = malformed.union(&RangeSet(vec![1, 2]));
1519 let _ = malformed.intersection(&RangeSet(vec![1, 2]));
1520 let _ = malformed.difference(&RangeSet(vec![1, 2]));
1521 let _ = malformed.has_intersection(&RangeSet(vec![1, 2]));
1522 let _ = malformed.contains_all(&RangeSet(vec![1, 2]));
1523 let _ = RangeSet(vec![1u8, 2]).contains_all(&malformed);
1524 let _ = RangeSet(vec![1u8, 2]).union(&malformed);
1525 let _ = RangeSet(vec![1u8, 2]).intersection(&malformed);
1526 let _ = RangeSet(vec![1u8, 2]).has_intersection(&malformed);
1527 }
1528
1529 Ok(())
1530 }
1531
1532 #[test]
1533 fn test_exhaustive_against_btree_set() -> Result<(), String> {
1534 const UNIVERSE: u8 = 7;
1535
1536 let subsets: Vec<(BTreeSet<u8>, RangeSet<u8>)> = (0..(1u32 << UNIVERSE))
1537 .map(|mask| {
1538 let values: Vec<u8> = (0..UNIVERSE)
1539 .filter(|value| mask & (1 << value) != 0)
1540 .collect();
1541 (
1542 values.iter().copied().collect(),
1543 range_set_from_values(&values),
1544 )
1545 })
1546 .collect();
1547
1548 for (values, range) in &subsets {
1549 assert_canonical(range);
1550 assert_eq!(*values, range.iter().collect::<BTreeSet<_>>());
1551 assert_eq!(values.is_empty(), range.is_empty());
1552
1553 let complement = range.complement();
1554 assert_canonical(&complement);
1555 assert_eq!(
1556 (0..=u8::MAX)
1557 .filter(|v| !values.contains(v))
1558 .collect::<BTreeSet<_>>(),
1559 complement.iter().collect::<BTreeSet<_>>()
1560 );
1561
1562 for value in 0..=UNIVERSE {
1563 assert_eq!(values.contains(&value), range.contains(value));
1564 }
1565 }
1566
1567 for (values1, range1) in &subsets {
1568 for (values2, range2) in &subsets {
1569 let union = range1.union(range2);
1570 assert_canonical(&union);
1571 assert_eq!(
1572 values1.union(values2).copied().collect::<BTreeSet<_>>(),
1573 union.iter().collect::<BTreeSet<_>>(),
1574 "{range1} union {range2}"
1575 );
1576
1577 let intersection = range1.intersection(range2);
1578 assert_canonical(&intersection);
1579 assert_eq!(
1580 values1
1581 .intersection(values2)
1582 .copied()
1583 .collect::<BTreeSet<_>>(),
1584 intersection.iter().collect::<BTreeSet<_>>(),
1585 "{range1} intersection {range2}"
1586 );
1587
1588 let difference = range1.difference(range2);
1589 assert_canonical(&difference);
1590 assert_eq!(
1591 values1
1592 .difference(values2)
1593 .copied()
1594 .collect::<BTreeSet<_>>(),
1595 difference.iter().collect::<BTreeSet<_>>(),
1596 "{range1} difference {range2}"
1597 );
1598
1599 assert_eq!(
1600 !values1.is_disjoint(values2),
1601 range1.has_intersection(range2),
1602 "{range1} has_intersection {range2}"
1603 );
1604 assert_eq!(
1605 values2.is_subset(values1),
1606 range1.contains_all(range2),
1607 "{range1} contains_all {range2}"
1608 );
1609
1610 if values1 == values2 {
1612 assert_eq!(range1, range2);
1613 }
1614 }
1615 }
1616
1617 Ok(())
1618 }
1619
1620 #[test]
1621 fn test_randomized_against_btree_set_over_the_whole_universe() -> Result<(), String> {
1622 let mut state = 0x2545_f491_4f6c_dd1du64;
1626 let mut next = move || {
1627 state ^= state << 13;
1628 state ^= state >> 7;
1629 state ^= state << 17;
1630 state
1631 };
1632
1633 let subsets: Vec<(BTreeSet<u8>, RangeSet<u8>)> = (0..200)
1634 .map(|_| {
1635 let density = (next() % 100) as u8;
1638 let values: Vec<u8> = (0..=u8::MAX)
1639 .filter(|_| (next() % 100) as u8 <= density)
1640 .collect();
1641 (
1642 values.iter().copied().collect(),
1643 range_set_from_values(&values),
1644 )
1645 })
1646 .collect();
1647
1648 for (values, range) in &subsets {
1649 assert_canonical(range);
1650 assert_eq!(*values, range.iter().collect::<BTreeSet<_>>());
1651
1652 let complement = range.complement();
1653 assert_canonical(&complement);
1654 assert_eq!(
1655 (0..=u8::MAX)
1656 .filter(|value| !values.contains(value))
1657 .collect::<BTreeSet<_>>(),
1658 complement.iter().collect::<BTreeSet<_>>(),
1659 "complement of {range}"
1660 );
1661 }
1662
1663 for (values1, range1) in &subsets {
1664 for (values2, range2) in &subsets {
1665 let union = range1.union(range2);
1666 assert_canonical(&union);
1667 assert_eq!(
1668 values1.union(values2).copied().collect::<BTreeSet<_>>(),
1669 union.iter().collect::<BTreeSet<_>>(),
1670 "{range1} union {range2}"
1671 );
1672
1673 let intersection = range1.intersection(range2);
1674 assert_canonical(&intersection);
1675 assert_eq!(
1676 values1
1677 .intersection(values2)
1678 .copied()
1679 .collect::<BTreeSet<_>>(),
1680 intersection.iter().collect::<BTreeSet<_>>(),
1681 "{range1} intersection {range2}"
1682 );
1683
1684 let difference = range1.difference(range2);
1685 assert_canonical(&difference);
1686 assert_eq!(
1687 values1
1688 .difference(values2)
1689 .copied()
1690 .collect::<BTreeSet<_>>(),
1691 difference.iter().collect::<BTreeSet<_>>(),
1692 "{range1} difference {range2}"
1693 );
1694
1695 assert_eq!(
1696 !values1.is_disjoint(values2),
1697 range1.has_intersection(range2),
1698 "{range1} has_intersection {range2}"
1699 );
1700 assert_eq!(
1701 values2.is_subset(values1),
1702 range1.contains_all(range2),
1703 "{range1} contains_all {range2}"
1704 );
1705 }
1706 }
1707
1708 Ok(())
1709 }
1710
1711 #[test]
1712 fn test_new_from_bounds_validation() -> Result<(), String> {
1713 assert_eq!(
1714 Some(RangeSet::<u8>::empty()),
1715 RangeSet::<u8>::new_from_bounds(vec![])
1716 );
1717 assert_eq!(
1718 Some(RangeSet::<u8>::new_from_range(2..=5)),
1719 RangeSet::<u8>::new_from_bounds(vec![2, 5])
1720 );
1721 assert_eq!(
1722 Some(RangeSet::<u8>::total()),
1723 RangeSet::<u8>::new_from_bounds(vec![0, 255])
1724 );
1725 assert_eq!(
1726 Some(RangeSet::<u8>(vec![2, 5, 7, 9])),
1727 RangeSet::<u8>::new_from_bounds(vec![2, 5, 7, 9])
1728 );
1729
1730 assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0]));
1732 assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0, 5, 7]));
1733 assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![5, 3]));
1735 assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![10, 20, 0, 5]));
1737 assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0, 5, 4, 9]));
1739 assert_eq!(None, RangeSet::<u8>::new_from_bounds(vec![0, 5, 6, 9]));
1741 assert_eq!(
1743 None,
1744 RangeSet::<u8>::new_from_bounds(vec![0, 255, 255, 255])
1745 );
1746
1747 Ok(())
1748 }
1749
1750 #[test]
1751 #[cfg(feature = "serde")]
1752 fn serde_rejects_malformed_range_set() {
1753 assert!(serde_json::from_str::<RangeSet<u8>>("[]").is_ok());
1754 assert!(serde_json::from_str::<RangeSet<u8>>("[0,5]").is_ok());
1755 assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,7,9]").is_ok());
1756
1757 assert!(serde_json::from_str::<RangeSet<u8>>("[0]").is_err());
1759 assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,7]").is_err());
1760 assert!(serde_json::from_str::<RangeSet<u8>>("[5,3]").is_err());
1762 assert!(serde_json::from_str::<RangeSet<u8>>("[10,20,0,5]").is_err());
1764 assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,4,9]").is_err());
1766 assert!(serde_json::from_str::<RangeSet<u8>>("[0,5,6,9]").is_err());
1768 }
1769}