geng_rodio/source/
done.rs

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