Skip to main content

truth_engine/
conflict.rs

1//! Detect overlapping events in expanded schedules.
2//!
3//! Performs pairwise comparison between two event lists to find time overlaps.
4//! Adjacent events (where one ends exactly when another starts) are NOT conflicts.
5
6use crate::expander::ExpandedEvent;
7
8/// A detected conflict between two events.
9#[derive(Debug, Clone, PartialEq)]
10pub struct Conflict {
11    pub event_a: ExpandedEvent,
12    pub event_b: ExpandedEvent,
13    pub overlap_minutes: i64,
14}
15
16/// Find all pairwise conflicts (overlapping time ranges) between two event lists.
17///
18/// Two events overlap when `a.start < b.end && b.start < a.end`.
19/// The overlap duration is `min(a.end, b.end) - max(a.start, b.start)`.
20///
21/// Adjacent events where one ends exactly when another starts are NOT conflicts.
22pub fn find_conflicts(events_a: &[ExpandedEvent], events_b: &[ExpandedEvent]) -> Vec<Conflict> {
23    let mut conflicts = Vec::new();
24
25    for a in events_a {
26        for b in events_b {
27            // Two intervals overlap iff a.start < b.end AND b.start < a.end.
28            // This excludes the adjacent case where a.end == b.start.
29            if a.start < b.end && b.start < a.end {
30                let overlap_start = a.start.max(b.start);
31                let overlap_end = a.end.min(b.end);
32                let overlap_minutes = (overlap_end - overlap_start).num_minutes();
33
34                conflicts.push(Conflict {
35                    event_a: a.clone(),
36                    event_b: b.clone(),
37                    overlap_minutes,
38                });
39            }
40        }
41    }
42
43    conflicts
44}