rodio/source/
skippable.rs

1use std::time::Duration;
2
3use crate::Sample;
4use crate::Source;
5
6use super::SeekError;
7
8/// Wrap the source in a skippable. It allows ending the current source early by
9/// calling [`Skippable::skip`]. If this source is in a queue such as the Sink
10/// ending the source early is equal to skipping the source.
11pub fn skippable<I>(source: I) -> Skippable<I> {
12    Skippable {
13        input: source,
14        do_skip: false,
15    }
16}
17
18/// Wrap the source in a skippable. It allows ending the current source early by
19/// calling [`Skippable::skip`]. If this source is in a queue such as the Sink
20/// ending the source early is equal to skipping the source.
21#[derive(Clone, Debug)]
22pub struct Skippable<I> {
23    input: I,
24    do_skip: bool,
25}
26
27impl<I> Skippable<I> {
28    /// Skips the current source
29    #[inline]
30    pub fn skip(&mut self) {
31        self.do_skip = true;
32    }
33
34    /// Returns a reference to the inner source.
35    #[inline]
36    pub fn inner(&self) -> &I {
37        &self.input
38    }
39
40    /// Returns a mutable reference to the inner source.
41    #[inline]
42    pub fn inner_mut(&mut self) -> &mut I {
43        &mut self.input
44    }
45
46    /// Returns the inner source.
47    #[inline]
48    pub fn into_inner(self) -> I {
49        self.input
50    }
51}
52
53impl<I> Iterator for Skippable<I>
54where
55    I: Source,
56    I::Item: Sample,
57{
58    type Item = I::Item;
59
60    #[inline]
61    fn next(&mut self) -> Option<I::Item> {
62        if self.do_skip {
63            None
64        } else {
65            self.input.next()
66        }
67    }
68
69    #[inline]
70    fn size_hint(&self) -> (usize, Option<usize>) {
71        self.input.size_hint()
72    }
73}
74
75impl<I> Source for Skippable<I>
76where
77    I: Source,
78    I::Item: Sample,
79{
80    #[inline]
81    fn current_frame_len(&self) -> Option<usize> {
82        self.input.current_frame_len()
83    }
84
85    #[inline]
86    fn channels(&self) -> u16 {
87        self.input.channels()
88    }
89
90    #[inline]
91    fn sample_rate(&self) -> u32 {
92        self.input.sample_rate()
93    }
94
95    #[inline]
96    fn total_duration(&self) -> Option<Duration> {
97        self.input.total_duration()
98    }
99
100    #[inline]
101    fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
102        self.input.try_seek(pos)
103    }
104}