diff --git a/Cargo.toml b/Cargo.toml index 7dd6a33..a4b06ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "discrete_range_map" -version = "0.6.0" +version = "0.6.1" authors = ["James Forster "] edition = "2021" description = """ diff --git a/src/discrete_range_map.rs b/src/discrete_range_map.rs index 0293d60..852dd37 100644 --- a/src/discrete_range_map.rs +++ b/src/discrete_range_map.rs @@ -1486,7 +1486,7 @@ pub trait InclusiveRange { self.start() <= self.end() } - ///requires that self comes before other and they don't overlap + /// requires that self comes before other and they don't overlap fn touches_ordered(&self, other: &Self) -> bool where I: PointType, @@ -1494,7 +1494,7 @@ pub trait InclusiveRange { self.end() == other.start().down().unwrap() } - ///requires that self comes before other + /// requires that self comes before other fn overlaps_ordered(&self, other: &Self) -> bool where I: PointType, @@ -1502,7 +1502,47 @@ pub trait InclusiveRange { self.contains(other.start()) || self.contains(other.end()) } - ///requires that self comes before other + /// Intersect the range with the other one, and return Some if the intersection is not empty. + fn intersect(&self, other: &Self) -> Option + where + I: PointType, + Self: From>, + { + let intersect_start = I::max(self.start(), other.start()); + let intersect_end = I::min(self.end(), other.end()); + if intersect_start <= intersect_end { + Some(Self::from(InclusiveInterval { + start: intersect_start, + end: intersect_end, + })) + } else { + None + } + } + + /// Move the entire range by the given amount. + fn translate(&self, delta: I) -> Self + where + I: PointType, + I: core::ops::Add, + Self: From>, + { + Self::from(InclusiveInterval { + start: self.start() + delta, + end: self.end() + delta, + }) + } + + /// The amount between the start and the end points of the range. + fn size(&self) -> I + where + I: PointType, + I: core::ops::Sub, + { + (self.end() - self.start()).up().unwrap() + } + + /// requires that self comes before other fn merge_ordered(&self, other: &Self) -> Self where Self: From>, @@ -2272,6 +2312,36 @@ mod tests { } } + #[test] + fn test_intersection() { + let input = InclusiveInterval { start: 5, end: 10 }; + assert_eq!( + input.intersect(&InclusiveInterval { start: 8, end: 13 }), + Some(InclusiveInterval { start: 8, end: 10 }) + ); + assert_eq!( + input.intersect(&InclusiveInterval { start: 10, end: 13 }), + Some(InclusiveInterval { start: 10, end: 10 }) + ); + assert_eq!( + input.intersect(&InclusiveInterval { start: 11, end: 13 }), + None + ); + } + + #[test] + fn test_translate() { + let input = InclusiveInterval { start: 5, end: 10 }; + assert_eq!(input.translate(3), InclusiveInterval { start: 8, end: 13 }); + assert_eq!(input.translate(-2), InclusiveInterval { start: 3, end: 8 }); + } + + #[test] + fn test_size() { + assert_eq!(InclusiveInterval { start: 5, end: 10 }.size(), 6); + assert_eq!(InclusiveInterval { start: 6, end: 6 }.size(), 1); + } + // Test Helper Functions //====================== fn all_non_overlapping_test_bound_entries()