audio_core/buf/
limit.rs

1use crate::{Buf, BufMut, Channel, ChannelMut, ExactSizeBuf, ReadBuf};
2
3/// A buffer that has been limited.
4///
5/// See [Buf::limit].
6pub struct Limit<B> {
7    buf: B,
8    limit: usize,
9}
10
11impl<B> Limit<B> {
12    /// Construct a new limited buffer.
13    pub(crate) fn new(buf: B, limit: usize) -> Self {
14        Self { buf, limit }
15    }
16}
17
18impl<B> Buf for Limit<B>
19where
20    B: Buf,
21{
22    type Sample = B::Sample;
23
24    type Channel<'this>
25        = B::Channel<'this>
26    where
27        Self: 'this;
28
29    type IterChannels<'this>
30        = IterChannels<B::IterChannels<'this>>
31    where
32        Self: 'this;
33
34    fn frames_hint(&self) -> Option<usize> {
35        let frames = self.buf.frames_hint()?;
36        Some(usize::min(frames, self.limit))
37    }
38
39    fn channels(&self) -> usize {
40        self.buf.channels()
41    }
42
43    fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
44        Some(self.buf.get_channel(channel)?.limit(self.limit))
45    }
46
47    fn iter_channels(&self) -> Self::IterChannels<'_> {
48        IterChannels {
49            iter: self.buf.iter_channels(),
50            limit: self.limit,
51        }
52    }
53}
54
55impl<B> BufMut for Limit<B>
56where
57    B: BufMut,
58{
59    type ChannelMut<'this>
60        = B::ChannelMut<'this>
61    where
62        Self: 'this;
63
64    type IterChannelsMut<'this>
65        = IterChannelsMut<B::IterChannelsMut<'this>>
66    where
67        Self: 'this;
68
69    fn get_channel_mut(&mut self, channel: usize) -> Option<Self::ChannelMut<'_>> {
70        Some(self.buf.get_channel_mut(channel)?.limit(self.limit))
71    }
72
73    fn copy_channel(&mut self, from: usize, to: usize)
74    where
75        Self::Sample: Copy,
76    {
77        self.buf.copy_channel(from, to);
78    }
79
80    fn iter_channels_mut(&mut self) -> Self::IterChannelsMut<'_> {
81        IterChannelsMut {
82            iter: self.buf.iter_channels_mut(),
83            limit: self.limit,
84        }
85    }
86}
87
88/// [Limit] adjusts the implementation of [ExactSizeBuf] to take the frame
89/// limiting into account.
90///
91/// ```
92/// use audio::{Buf, ExactSizeBuf};
93///
94/// let buf = audio::interleaved![[0; 4]; 2];
95///
96/// assert_eq!((&buf).limit(0).frames(), 0);
97/// assert_eq!((&buf).limit(1).frames(), 1);
98/// assert_eq!((&buf).limit(5).frames(), 4);
99/// ```
100impl<B> ExactSizeBuf for Limit<B>
101where
102    B: ExactSizeBuf,
103{
104    fn frames(&self) -> usize {
105        usize::min(self.buf.frames(), self.limit)
106    }
107}
108
109impl<B> ReadBuf for Limit<B>
110where
111    B: ReadBuf,
112{
113    fn remaining(&self) -> usize {
114        usize::min(self.buf.remaining(), self.limit)
115    }
116
117    fn advance(&mut self, n: usize) {
118        self.buf.advance(usize::min(n, self.limit));
119    }
120}
121
122iterators!(limit: usize => self.limit(limit));