crate_activity/
intersect_date_ranges.rs

1crate::ix!();
2
3pub fn intersect_date_ranges(
4    dates_a: &[NaiveDate],
5    dates_b: &[NaiveDate],
6) -> Vec<NaiveDate> {
7    let set_a: HashSet<_> = dates_a.iter().cloned().collect();
8    let set_b: HashSet<_> = dates_b.iter().cloned().collect();
9    let mut intersection: Vec<NaiveDate> = set_a.intersection(&set_b).cloned().collect();
10    intersection.sort(); // Ensure the output is sorted
11    intersection
12}
13
14#[cfg(test)]
15mod intersect_date_ranges_tests {
16    use super::*;
17    use chrono::NaiveDate;
18    use std::collections::HashSet;
19
20    #[test]
21    fn test_empty_inputs() {
22        let dates_a: Vec<NaiveDate> = vec![];
23        let dates_b: Vec<NaiveDate> = vec![];
24        let result = intersect_date_ranges(&dates_a, &dates_b);
25        assert!(result.is_empty(), "Intersection of empty inputs should be empty.");
26    }
27
28    #[test]
29    fn test_non_overlapping_date_ranges() {
30        let dates_a = vec![
31            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
32            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
33        ];
34        let dates_b = vec![
35            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
36            NaiveDate::from_ymd_opt(2024, 1, 4).unwrap(),
37        ];
38        let result = intersect_date_ranges(&dates_a, &dates_b);
39        assert!(result.is_empty(), "Non-overlapping ranges should yield an empty intersection.");
40    }
41
42    #[test]
43    fn test_identical_date_ranges() {
44        let dates_a = vec![
45            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
46            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
47            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
48        ];
49        let dates_b = dates_a.clone();
50        let result = intersect_date_ranges(&dates_a, &dates_b);
51        assert_eq!(result.len(), dates_a.len(), "Intersection of identical ranges should match their length.");
52        assert_eq!(result, dates_a, "Intersection of identical ranges should yield the same dates.");
53    }
54
55    #[test]
56    fn test_partially_overlapping_date_ranges() {
57        let dates_a = vec![
58            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
59            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
60            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
61        ];
62        let dates_b = vec![
63            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
64            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
65            NaiveDate::from_ymd_opt(2024, 1, 4).unwrap(),
66        ];
67        let result = intersect_date_ranges(&dates_a, &dates_b);
68        let expected = vec![
69            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
70            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
71        ];
72        assert_eq!(result, expected, "Intersection should yield only overlapping dates.");
73    }
74
75    #[test]
76    fn test_subset_date_ranges() {
77        let dates_a = vec![
78            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
79            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
80            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
81        ];
82        let dates_b = vec![
83            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
84            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
85        ];
86        let result = intersect_date_ranges(&dates_a, &dates_b);
87        assert_eq!(result, dates_b, "Intersection should match the smaller range if it's a subset.");
88    }
89
90    #[test]
91    fn test_disjoint_ranges_with_duplicates() {
92        let dates_a = vec![
93            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
94            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), // Duplicate
95            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
96        ];
97        let dates_b = vec![
98            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
99            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
100            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(), // Duplicate
101        ];
102        let result = intersect_date_ranges(&dates_a, &dates_b);
103        let expected = vec![NaiveDate::from_ymd_opt(2024, 1, 2).unwrap()];
104        assert_eq!(result, expected, "Intersection should ignore duplicates and yield correct results.");
105    }
106}