1use std::ops::RangeInclusive;
5use itertools::{Itertools, MinMaxResult};
6
7pub trait IteratorExt: Iterator + Sized {
9 fn range(self) -> Option<RangeInclusive<Self::Item>>
12 where Self::Item: Ord + Copy {
13 match self.minmax() {
14 MinMaxResult::NoElements => None,
15 MinMaxResult::OneElement(x) => Some(x ..= x),
16 MinMaxResult::MinMax(min, max) => Some(min ..= max),
17 }
18 }
19}
20
21impl<I: Iterator> IteratorExt for I {}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26
27 #[test]
28 fn range_empty() {
29 let r: Option<RangeInclusive<i32>> = std::iter::empty().range();
30 assert_eq!(r, None);
31 }
32
33 #[test]
34 fn range_single() {
35 assert_eq!([7].into_iter().range(), Some(7 ..= 7));
36 }
37
38 #[test]
39 fn range_sorted() {
40 assert_eq!([1, 2, 3, 4, 5].into_iter().range(), Some(1 ..= 5));
41 }
42
43 #[test]
44 fn range_unsorted() {
45 assert_eq!([3, -2, 5, 1, -7, 4].into_iter().range(), Some(-7 ..= 5));
46 }
47
48 #[test]
49 fn range_duplicates() {
50 assert_eq!([2, 2, 2].into_iter().range(), Some(2 ..= 2));
51 }
52}