rodio/source/
done.rs

1use std::sync::atomic::{AtomicUsize, Ordering};
2use std::sync::Arc;
3use std::time::Duration;
4
5use super::SeekError;
6use crate::common::{ChannelCount, SampleRate};
7use crate::Source;
8
9/// When the inner source is empty this decrements a `AtomicUsize`.
10#[derive(Debug, Clone)]
11pub struct Done<I> {
12    input: I,
13    signal: Arc<AtomicUsize>,
14    signal_sent: bool,
15}
16
17impl<I> Done<I> {
18    /// When the inner source is empty the AtomicUsize passed in is decremented.
19    /// If it was zero it will overflow negatively.
20    #[inline]
21    pub fn new(input: I, signal: Arc<AtomicUsize>) -> Done<I> {
22        Done {
23            input,
24            signal,
25            signal_sent: false,
26        }
27    }
28
29    /// Returns a reference to the inner source.
30    #[inline]
31    pub fn inner(&self) -> &I {
32        &self.input
33    }
34
35    /// Returns a mutable reference to the inner source.
36    #[inline]
37    pub fn inner_mut(&mut self) -> &mut I {
38        &mut self.input
39    }
40
41    /// Returns the inner source.
42    #[inline]
43    pub fn into_inner(self) -> I {
44        self.input
45    }
46}
47
48impl<I: Source> Iterator for Done<I>
49where
50    I: Source,
51{
52    type Item = I::Item;
53
54    #[inline]
55    fn next(&mut self) -> Option<I::Item> {
56        let next = self.input.next();
57        if !self.signal_sent && next.is_none() {
58            self.signal.fetch_sub(1, Ordering::Relaxed);
59            self.signal_sent = true;
60        }
61        next
62    }
63
64    fn size_hint(&self) -> (usize, Option<usize>) {
65        self.input.size_hint()
66    }
67}
68
69impl<I> Source for Done<I>
70where
71    I: Source,
72{
73    #[inline]
74    fn current_span_len(&self) -> Option<usize> {
75        self.input.current_span_len()
76    }
77
78    #[inline]
79    fn channels(&self) -> ChannelCount {
80        self.input.channels()
81    }
82
83    #[inline]
84    fn sample_rate(&self) -> SampleRate {
85        self.input.sample_rate()
86    }
87
88    #[inline]
89    fn total_duration(&self) -> Option<Duration> {
90        self.input.total_duration()
91    }
92
93    #[inline]
94    fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
95        self.input.try_seek(pos)
96    }
97}