dw_transform/
period_union.rs1use super::sort::sort_by_timestamp;
2use dw_models::Event;
3use std::collections::VecDeque;
4
5pub fn period_union(events1: &[Event], events2: &[Event]) -> Vec<Event> {
20 let mut sorted_events: VecDeque<Event> = VecDeque::new();
21 sorted_events.extend(sort_by_timestamp([events1, events2].concat()));
22
23 let mut events_union = Vec::new();
24
25 if !events1.is_empty() {
26 events_union.push(sorted_events.pop_front().unwrap())
27 }
28
29 for e in sorted_events {
30 let last_event = events_union.last().unwrap();
31
32 let e_p = e.interval();
33 let le_p = last_event.interval();
34
35 match e_p.union(&le_p) {
36 Some(new_period) => {
37 let mut e_mod = events_union.pop().unwrap();
39 e_mod.duration = new_period.duration();
40 events_union.push(e_mod);
41 }
42 None => {
43 events_union.push(e);
45 }
46 }
47 }
48
49 events_union
50 .drain(..)
51 .map(|mut e| {
52 e.data = json_map! {};
53 e
54 })
55 .collect()
56}
57
58#[cfg(test)]
59mod tests {
60 use std::str::FromStr;
61
62 use chrono::DateTime;
63 use chrono::Duration;
64 use chrono::Utc;
65 use serde_json::json;
66
67 use dw_models::Event;
68
69 use super::period_union;
70
71 #[test]
72 fn test_period_union_empty() {
73 let e_result = period_union(&[], &[]);
74 assert_eq!(e_result.len(), 0);
75 }
76
77 #[test]
78 fn test_period_union() {
79 let e1 = Event {
80 id: None,
81 timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(),
82 duration: Duration::seconds(1),
83 data: json_map! {"test": json!(1)},
84 };
85
86 let mut e2 = e1.clone();
87 e2.timestamp = DateTime::from_str("2000-01-01T00:00:02Z").unwrap();
88
89 let e_result = period_union(&[e1], &[e2]);
90 assert_eq!(e_result.len(), 1);
91
92 let dt: DateTime<Utc> = DateTime::from_str("2000-01-01T00:00:01.000Z").unwrap();
93 assert_eq!(e_result[0].timestamp, dt);
94 assert_eq!(e_result[0].duration, Duration::milliseconds(2000));
95 }
96
97 #[test]
99 fn test_period_union_nop() {
100 let e1 = Event {
101 id: None,
102 timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(),
103 duration: Duration::seconds(1),
104 data: json_map! {"test": json!(1)},
105 };
106
107 let mut e2 = e1.clone();
108 e2.timestamp = DateTime::from_str("2000-01-01T00:00:03Z").unwrap();
109
110 let e_result = period_union(&[e1], &[e2]);
111 assert_eq!(e_result.len(), 2);
112 }
113}