Skip to main content

clack_common/events/io/
merger.rs

1use crate::events::UnknownEvent;
2use std::mem::replace;
3
4/// An iterator that merges two ordered streams of events together.
5///
6/// This wraps two distinct event iterators and produces all the events produced by both, but in
7/// order.
8pub struct EventMerger<'a, I1, I2> {
9    iter_1: I1,
10    iter_2: I2,
11
12    event_1: Option<&'a UnknownEvent>,
13    event_2: Option<&'a UnknownEvent>,
14    started: bool,
15}
16
17impl<I1, I2> EventMerger<'_, I1, I2> {
18    /// Creates a new event merger from two iterators.
19    #[inline]
20    pub const fn new(iter_1: I1, iter_2: I2) -> Self {
21        Self {
22            iter_1,
23            iter_2,
24            event_1: None,
25            event_2: None,
26            started: false,
27        }
28    }
29}
30
31impl<'a, I1, I2> Iterator for EventMerger<'a, I1, I2>
32where
33    I1: Iterator<Item = &'a UnknownEvent>,
34    I2: Iterator<Item = &'a UnknownEvent>,
35{
36    type Item = &'a UnknownEvent;
37
38    #[inline]
39    fn next(&mut self) -> Option<Self::Item> {
40        if !self.started {
41            self.event_1 = self.iter_1.next();
42            self.event_2 = self.iter_2.next();
43
44            self.started = true;
45        }
46
47        match (&self.event_1, &self.event_2) {
48            (Some(e1), Some(e2)) if e1.header() <= e2.header() => {
49                replace(&mut self.event_1, self.iter_1.next())
50            }
51            (Some(_), None) => replace(&mut self.event_1, self.iter_1.next()),
52            (_, Some(_)) => replace(&mut self.event_2, self.iter_2.next()),
53            (None, None) => None,
54        }
55    }
56}
57
58#[cfg(test)]
59mod test {
60    use crate::events::Event;
61    use crate::events::event_types::MidiEvent;
62    use crate::events::io::merger::EventMerger;
63
64    #[test]
65    fn it_works() {
66        let event_0 = MidiEvent::new(0, 0, [0; 3]);
67        let event_1 = MidiEvent::new(1, 0, [1; 3]);
68        let event_2 = MidiEvent::new(2, 0, [2; 3]);
69        let event_3 = MidiEvent::new(3, 0, [3; 3]);
70
71        let events_1 = [event_1, event_2];
72        let events_2 = [event_0, event_3];
73
74        let mut merger = EventMerger::new(
75            events_1.iter().map(|e| e.as_unknown()),
76            events_2.iter().map(|e| e.as_unknown()),
77        );
78
79        assert_eq!(Some(&event_0), merger.next().unwrap().as_event());
80        assert_eq!(Some(&event_1), merger.next().unwrap().as_event());
81        assert_eq!(Some(&event_2), merger.next().unwrap().as_event());
82        assert_eq!(Some(&event_3), merger.next().unwrap().as_event());
83        assert!(merger.next().is_none());
84        assert!(merger.next().is_none());
85    }
86}