use crate::common::*; pub(crate) trait RangeExt { fn range_contains(&self, i: &T) -> bool; fn display(&self) -> DisplayRange<&Self> { DisplayRange(self) } } pub(crate) struct DisplayRange(T); impl Display for DisplayRange<&Range> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { if self.0.start == self.0.end { write!(f, "{}", self.0.start)?; } else if self.0.end == usize::MAX { write!(f, "{} or more", self.0.start)?; } else { write!(f, "{} to {}", self.0.start, self.0.end)?; } Ok(()) } } impl RangeExt for Range where T: PartialOrd, { fn range_contains(&self, i: &T) -> bool { i >= &self.start && i < &self.end } } impl RangeExt for RangeInclusive where T: PartialOrd, { fn range_contains(&self, i: &T) -> bool { i >= self.start() && i <= self.end() } } #[cfg(test)] mod tests { use super::*; #[test] fn exclusive() { assert!(!(0..0).range_contains(&0)); assert!(!(0..0).range_contains(&0)); assert!(!(1..10).range_contains(&0)); assert!(!(1..10).range_contains(&10)); assert!(!(1..10).range_contains(&0)); assert!(!(1..10).range_contains(&10)); assert!((0..1).range_contains(&0)); assert!((0..1).range_contains(&0)); assert!((10..20).range_contains(&15)); assert!((10..20).range_contains(&15)); } #[test] fn inclusive() { assert!(!(0..=10).range_contains(&11)); assert!(!(1..=10).range_contains(&0)); assert!(!(5..=10).range_contains(&4)); assert!((0..=0).range_contains(&0)); assert!((0..=1).range_contains(&0)); assert!((0..=10).range_contains(&0)); assert!((0..=10).range_contains(&10)); assert!((0..=10).range_contains(&7)); assert!((1..=10).range_contains(&10)); assert!((10..=20).range_contains(&15)); } #[test] fn display() { assert_eq!((1..1).display().to_string(), "1"); assert_eq!((1..2).display().to_string(), "1 to 2"); assert_eq!((1..usize::MAX).display().to_string(), "1 or more"); } }