rodio/source/
repeat.rs

1use std::time::Duration;
2
3use crate::source::buffered::Buffered;
4
5use crate::{Sample, Source};
6
7use super::SeekError;
8
9/// Internal function that builds a `Repeat` object.
10pub fn repeat<I>(input: I) -> Repeat<I>
11where
12    I: Source,
13    I::Item: Sample,
14{
15    let input = input.buffered();
16    Repeat {
17        inner: input.clone(),
18        next: input,
19    }
20}
21
22/// A source that repeats the given source.
23pub struct Repeat<I>
24where
25    I: Source,
26    I::Item: Sample,
27{
28    inner: Buffered<I>,
29    next: Buffered<I>,
30}
31
32impl<I> Iterator for Repeat<I>
33where
34    I: Source,
35    I::Item: Sample,
36{
37    type Item = <I as Iterator>::Item;
38
39    #[inline]
40    fn next(&mut self) -> Option<<I as Iterator>::Item> {
41        if let Some(value) = self.inner.next() {
42            return Some(value);
43        }
44
45        self.inner = self.next.clone();
46        self.inner.next()
47    }
48
49    #[inline]
50    fn size_hint(&self) -> (usize, Option<usize>) {
51        // infinite
52        (0, None)
53    }
54}
55
56impl<I> Source for Repeat<I>
57where
58    I: Iterator + Source,
59    I::Item: Sample,
60{
61    #[inline]
62    fn current_frame_len(&self) -> Option<usize> {
63        match self.inner.current_frame_len() {
64            Some(0) => self.next.current_frame_len(),
65            a => a,
66        }
67    }
68
69    #[inline]
70    fn channels(&self) -> u16 {
71        match self.inner.current_frame_len() {
72            Some(0) => self.next.channels(),
73            _ => self.inner.channels(),
74        }
75    }
76
77    #[inline]
78    fn sample_rate(&self) -> u32 {
79        match self.inner.current_frame_len() {
80            Some(0) => self.next.sample_rate(),
81            _ => self.inner.sample_rate(),
82        }
83    }
84
85    #[inline]
86    fn total_duration(&self) -> Option<Duration> {
87        None
88    }
89
90    #[inline]
91    fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
92        self.inner.try_seek(pos)
93    }
94}
95
96impl<I> Clone for Repeat<I>
97where
98    I: Source,
99    I::Item: Sample,
100{
101    #[inline]
102    fn clone(&self) -> Repeat<I> {
103        Repeat {
104            inner: self.inner.clone(),
105            next: self.next.clone(),
106        }
107    }
108}