Skip to main content

midi_toolkit/sequence/
extensions.rs

1use std::fmt::Debug;
2
3use crate::{
4    events::{BatchTempo, CastEventDelta, MIDIDelta, MIDIEvent, MIDIEventEnum},
5    notes::{MIDINote, Note},
6    num::MIDINum,
7};
8
9use super::{
10    common::{to_vec_result, unwrap_items, wrap_ok, TimeCaster},
11    conversion::{events_to_notes, notes_to_events},
12    event::{
13        cancel_tempo_events, convert_events_into_batches, filter_events, filter_map_events,
14        filter_non_note_events, filter_note_events, get_channel_statistics,
15        get_channels_array_statistics, into_track_events, merge_events_array, scale_event_ppq,
16        scale_event_time, ChannelGroupStatistics, ChannelStatistics, Delta, EventBatch, Track,
17    },
18    note::merge_notes_iterator,
19};
20
21pub trait IntoOkExt: Iterator + Sized {
22    fn into_ok(self) -> impl Iterator<Item = Result<Self::Item, ()>> {
23        wrap_ok(self)
24    }
25}
26
27impl<I: Iterator> IntoOkExt for I {}
28
29pub trait ResultIterExt<T, Err>: Iterator<Item = Result<T, Err>> + Sized {
30    fn unwrap_items(self) -> impl Iterator<Item = T>
31    where
32        T: Debug,
33        Err: Debug,
34    {
35        unwrap_items(self)
36    }
37
38    fn collect_vec_result(self) -> Result<Vec<T>, Err> {
39        to_vec_result(self)
40    }
41}
42
43impl<T, Err, I> ResultIterExt<T, Err> for I where I: Iterator<Item = Result<T, Err>> + Sized {}
44
45pub trait EventSequenceExt<D: MIDINum, E, Err>:
46    Iterator<Item = Result<Delta<D, E>, Err>> + Sized
47{
48    fn cast_event_delta<ND: MIDINum>(
49        self,
50    ) -> impl Iterator<Item = Result<<Delta<D, E> as CastEventDelta<ND>>::Output, Err>>
51    where
52        Delta<D, E>: CastEventDelta<ND>,
53    {
54        TimeCaster::<ND>::cast_event_delta(self)
55    }
56
57    fn scale_event_time(self, multiplier: D) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
58    where
59        Delta<D, E>: MIDIDelta<D>,
60    {
61        scale_event_time(self, multiplier)
62    }
63
64    fn scale_event_ppq(self, from: D, to: D) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
65    where
66        Delta<D, E>: MIDIEvent + MIDIDelta<D>,
67    {
68        scale_event_ppq(self, from, to)
69    }
70
71    fn filter_events(
72        self,
73        predicate: impl Fn(&Delta<D, E>) -> bool,
74    ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
75    where
76        Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,
77    {
78        filter_events(self, predicate)
79    }
80
81    fn filter_map_events<NE>(
82        self,
83        mapper: impl FnMut(E) -> Option<NE>,
84    ) -> impl Iterator<Item = Result<Delta<D, NE>, Err>> {
85        filter_map_events(self, mapper)
86    }
87
88    fn filter_note_events(self) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
89    where
90        Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,
91    {
92        filter_note_events(self)
93    }
94
95    fn filter_non_note_events(self) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
96    where
97        Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,
98    {
99        filter_non_note_events(self)
100    }
101
102    fn cancel_tempo_events(self, new_tempo: u32) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
103    where
104        Delta<D, E>: BatchTempo + MIDIDelta<D>,
105    {
106        cancel_tempo_events(self, new_tempo)
107    }
108
109    fn event_batches(self) -> impl Iterator<Item = Result<Delta<D, EventBatch<E>>, Err>>
110    where
111        Delta<D, E>: MIDIDelta<D>,
112    {
113        convert_events_into_batches(self)
114    }
115
116    fn into_track_events(
117        self,
118        track: u32,
119    ) -> impl Iterator<Item = Result<Delta<D, Track<E>>, Err>> {
120        into_track_events(self, track)
121    }
122
123    fn events_to_notes(self) -> impl Iterator<Item = Result<Note<D>, Err>>
124    where
125        E: MIDIEventEnum,
126    {
127        events_to_notes(self)
128    }
129
130    fn channel_statistics(self) -> Result<ChannelStatistics<D>, Err>
131    where
132        Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,
133    {
134        get_channel_statistics(self)
135    }
136}
137
138impl<D: MIDINum, E, Err, I> EventSequenceExt<D, E, Err> for I where
139    I: Iterator<Item = Result<Delta<D, E>, Err>> + Sized
140{
141}
142
143pub trait EventSequenceCollectionExt<D: MIDINum, T, Err, I>: Iterator<Item = I> + Sized
144where
145    T: MIDIDelta<D>,
146    I: Iterator<Item = Result<T, Err>> + Sized,
147{
148    fn merge_all(self) -> impl Iterator<Item = Result<T, Err>> {
149        merge_events_array(self.collect())
150    }
151
152    fn channel_statistics(self) -> Result<ChannelGroupStatistics<D>, Err>
153    where
154        T: MIDIEventEnum + MIDIDelta<D>,
155        Err: Send,
156        I: Send,
157    {
158        get_channels_array_statistics(self.collect())
159    }
160}
161
162impl<D: MIDINum, T, Err, I, II> EventSequenceCollectionExt<D, T, Err, I> for II
163where
164    T: MIDIDelta<D>,
165    I: Iterator<Item = Result<T, Err>> + Sized,
166    II: Iterator<Item = I> + Sized,
167{
168}
169
170pub trait NoteSequenceExt<D: MIDINum, N, Err>: Iterator<Item = Result<N, Err>> + Sized
171where
172    N: MIDINote<D>,
173{
174    fn notes_to_events(self) -> impl Iterator<Item = Result<Delta<D, crate::events::Event>, Err>> {
175        notes_to_events(self)
176    }
177}
178
179impl<D: MIDINum, N, Err, I> NoteSequenceExt<D, N, Err> for I
180where
181    N: MIDINote<D>,
182    I: Iterator<Item = Result<N, Err>> + Sized,
183{
184}
185
186pub trait NoteSequenceCollectionExt<D: MIDINum, N, Err, I>: Iterator<Item = I> + Sized
187where
188    N: MIDINote<D>,
189    I: Iterator<Item = Result<N, Err>> + Sized,
190{
191    fn merge_all(self) -> impl Iterator<Item = Result<N, Err>> {
192        merge_notes_iterator(self)
193    }
194}
195
196impl<D: MIDINum, N, Err, I, II> NoteSequenceCollectionExt<D, N, Err, I> for II
197where
198    N: MIDINote<D>,
199    I: Iterator<Item = Result<N, Err>> + Sized,
200    II: Iterator<Item = I> + Sized,
201{
202}