crate_activity/
intersect_date_ranges.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
crate::ix!();

pub fn intersect_date_ranges(
    dates_a: &[NaiveDate],
    dates_b: &[NaiveDate],
) -> Vec<NaiveDate> {
    let set_a: HashSet<_> = dates_a.iter().cloned().collect();
    let set_b: HashSet<_> = dates_b.iter().cloned().collect();
    let mut intersection: Vec<NaiveDate> = set_a.intersection(&set_b).cloned().collect();
    intersection.sort(); // Ensure the output is sorted
    intersection
}

#[cfg(test)]
mod intersect_date_ranges_tests {
    use super::*;
    use chrono::NaiveDate;
    use std::collections::HashSet;

    #[test]
    fn test_empty_inputs() {
        let dates_a: Vec<NaiveDate> = vec![];
        let dates_b: Vec<NaiveDate> = vec![];
        let result = intersect_date_ranges(&dates_a, &dates_b);
        assert!(result.is_empty(), "Intersection of empty inputs should be empty.");
    }

    #[test]
    fn test_non_overlapping_date_ranges() {
        let dates_a = vec![
            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
        ];
        let dates_b = vec![
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 4).unwrap(),
        ];
        let result = intersect_date_ranges(&dates_a, &dates_b);
        assert!(result.is_empty(), "Non-overlapping ranges should yield an empty intersection.");
    }

    #[test]
    fn test_identical_date_ranges() {
        let dates_a = vec![
            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
        ];
        let dates_b = dates_a.clone();
        let result = intersect_date_ranges(&dates_a, &dates_b);
        assert_eq!(result.len(), dates_a.len(), "Intersection of identical ranges should match their length.");
        assert_eq!(result, dates_a, "Intersection of identical ranges should yield the same dates.");
    }

    #[test]
    fn test_partially_overlapping_date_ranges() {
        let dates_a = vec![
            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
        ];
        let dates_b = vec![
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 4).unwrap(),
        ];
        let result = intersect_date_ranges(&dates_a, &dates_b);
        let expected = vec![
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
        ];
        assert_eq!(result, expected, "Intersection should yield only overlapping dates.");
    }

    #[test]
    fn test_subset_date_ranges() {
        let dates_a = vec![
            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
        ];
        let dates_b = vec![
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
        ];
        let result = intersect_date_ranges(&dates_a, &dates_b);
        assert_eq!(result, dates_b, "Intersection should match the smaller range if it's a subset.");
    }

    #[test]
    fn test_disjoint_ranges_with_duplicates() {
        let dates_a = vec![
            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), // Duplicate
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
        ];
        let dates_b = vec![
            NaiveDate::from_ymd_opt(2024, 1, 2).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(),
            NaiveDate::from_ymd_opt(2024, 1, 3).unwrap(), // Duplicate
        ];
        let result = intersect_date_ranges(&dates_a, &dates_b);
        let expected = vec![NaiveDate::from_ymd_opt(2024, 1, 2).unwrap()];
        assert_eq!(result, expected, "Intersection should ignore duplicates and yield correct results.");
    }
}