rodio/source/
from_iter.rs1use std::time::Duration;
2
3use super::SeekError;
4use crate::common::{ChannelCount, SampleRate};
5use crate::Source;
6
7pub fn from_iter<I>(iterator: I) -> FromIter<I::IntoIter>
15where
16 I: IntoIterator,
17{
18 let mut iterator = iterator.into_iter();
19 let first_source = iterator.next();
20
21 FromIter {
22 iterator,
23 current_source: first_source,
24 }
25}
26
27#[derive(Clone)]
29pub struct FromIter<I>
30where
31 I: Iterator,
32{
33 iterator: I,
35 current_source: Option<I::Item>,
37}
38
39impl<I> Iterator for FromIter<I>
40where
41 I: Iterator,
42 I::Item: Iterator + Source,
43{
44 type Item = <I::Item as Iterator>::Item;
45
46 #[inline]
47 fn next(&mut self) -> Option<Self::Item> {
48 loop {
49 if let Some(src) = &mut self.current_source {
50 if let Some(value) = src.next() {
51 return Some(value);
52 }
53 }
54
55 if let Some(src) = self.iterator.next() {
56 self.current_source = Some(src);
57 } else {
58 return None;
59 }
60 }
61 }
62
63 #[inline]
64 fn size_hint(&self) -> (usize, Option<usize>) {
65 if let Some(cur) = &self.current_source {
66 (cur.size_hint().0, None)
67 } else {
68 (0, None)
69 }
70 }
71}
72
73impl<I> Source for FromIter<I>
74where
75 I: Iterator,
76 I::Item: Iterator + Source,
77{
78 #[inline]
79 fn current_span_len(&self) -> Option<usize> {
80 const THRESHOLD: usize = 10240;
91
92 if let Some(src) = &self.current_source {
94 if let Some(val) = src.current_span_len() {
95 if val != 0 {
96 return Some(val);
97 }
98 }
99 }
100
101 if let Some(src) = &self.current_source {
103 if let Some(val) = src.size_hint().1 {
104 if val < THRESHOLD && val != 0 {
105 return Some(val);
106 }
107 }
108 }
109
110 Some(THRESHOLD)
112 }
113
114 #[inline]
115 fn channels(&self) -> ChannelCount {
116 if let Some(src) = &self.current_source {
117 src.channels()
118 } else {
119 2
121 }
122 }
123
124 #[inline]
125 fn sample_rate(&self) -> SampleRate {
126 if let Some(src) = &self.current_source {
127 src.sample_rate()
128 } else {
129 44100
131 }
132 }
133
134 #[inline]
135 fn total_duration(&self) -> Option<Duration> {
136 None
137 }
138
139 #[inline]
140 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
141 if let Some(source) = self.current_source.as_mut() {
142 source.try_seek(pos)
143 } else {
144 Ok(())
145 }
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use crate::buffer::SamplesBuffer;
152 use crate::source::{from_iter, Source};
153
154 #[test]
155 fn basic() {
156 let mut rx = from_iter((0..2).map(|n| {
157 if n == 0 {
158 SamplesBuffer::new(1, 48000, vec![10.0, -10.0, 10.0, -10.0])
159 } else if n == 1 {
160 SamplesBuffer::new(2, 96000, vec![5.0, 5.0, 5.0, 5.0])
161 } else {
162 unreachable!()
163 }
164 }));
165
166 assert_eq!(rx.channels(), 1);
167 assert_eq!(rx.sample_rate(), 48000);
168 assert_eq!(rx.next(), Some(10.0));
169 assert_eq!(rx.next(), Some(-10.0));
170 assert_eq!(rx.next(), Some(10.0));
171 assert_eq!(rx.next(), Some(-10.0));
172 assert_eq!(rx.next(), Some(5.0));
176 assert_eq!(rx.next(), Some(5.0));
177 assert_eq!(rx.next(), Some(5.0));
178 assert_eq!(rx.next(), Some(5.0));
179 assert_eq!(rx.next(), None);
180 }
181}