generic_arraydeque/
io.rs

1use core::str::{from_utf8, from_utf8_unchecked};
2use std::io::{self, BufRead, IoSlice, Read, Write};
3
4use super::{ArrayLength, GenericArrayDeque};
5
6impl<N: ArrayLength> GenericArrayDeque<u8, N> {
7  #[cfg_attr(not(tarpaulin), inline(always))]
8  fn extend_bytes(&mut self, buf: &[u8]) {
9    let written = unsafe {
10      self.write_iter_wrapping(
11        self.to_physical_idx(self.len),
12        buf.iter().copied(),
13        buf.len(),
14      )
15    };
16
17    debug_assert_eq!(
18      buf.len(),
19      written,
20      "The number of items written to VecDeque doesn't match the TrustedLen size hint"
21    );
22  }
23}
24
25/// Read is implemented for `GenericArrayDeque<u8>` by consuming bytes from the front of the `GenericArrayDeque`.
26impl<N: ArrayLength> Read for GenericArrayDeque<u8, N> {
27  /// Fill `buf` with the contents of the "front" slice as returned by
28  /// [`as_slices`][`GenericArrayDeque::as_slices`]. If the contained byte slices of the `GenericArrayDeque` are
29  /// discontiguous, multiple calls to `read` will be needed to read the entire content.
30  #[inline]
31  fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
32    let (ref mut front, _) = self.as_slices();
33    let n = Read::read(front, buf)?;
34    self.drain(..n);
35    Ok(n)
36  }
37
38  #[inline]
39  fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
40    let (front, back) = self.as_slices();
41
42    // Use only the front buffer if it is big enough to fill `buf`, else use
43    // the back buffer too.
44    match SplitAtMut::split_at_mut_checked(buf, front.len()) {
45      None => buf.copy_from_slice(&front[..buf.len()]),
46      Some((buf_front, buf_back)) => match SplitAt::split_at_checked(back, buf_back.len()) {
47        Some((back, _)) => {
48          buf_front.copy_from_slice(front);
49          buf_back.copy_from_slice(back);
50        }
51        None => {
52          self.clear();
53          return Err(io::Error::new(
54            io::ErrorKind::UnexpectedEof,
55            "failed to fill whole buffer",
56          ));
57        }
58      },
59    }
60
61    self.drain(..buf.len());
62    Ok(())
63  }
64
65  #[inline]
66  fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
67    // The total len is known upfront so we can reserve it in a single call.
68    let len = self.len();
69    buf
70      .try_reserve(len)
71      .map_err(|_| io::ErrorKind::OutOfMemory)?;
72
73    let (front, back) = self.as_slices();
74    buf.extend_from_slice(front);
75    buf.extend_from_slice(back);
76    self.clear();
77    Ok(len)
78  }
79
80  #[inline]
81  fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
82    let (front, back) = self.as_slices();
83    if from_utf8(front).is_err() || from_utf8(back).is_err() {
84      return Err(io::Error::new(
85        io::ErrorKind::InvalidData,
86        "stream did not contain valid UTF-8",
87      ));
88    }
89
90    let len = self.len();
91    buf
92      .try_reserve(len)
93      .map_err(|_| io::ErrorKind::OutOfMemory)?;
94
95    // SAFETY: We have already verified that the data is valid UTF-8
96    unsafe {
97      buf.push_str(from_utf8_unchecked(front));
98      buf.push_str(from_utf8_unchecked(back));
99    }
100    Ok(len)
101  }
102}
103
104/// BufRead is implemented for `GenericArrayDeque<u8>` by reading bytes from the front of the `GenericArrayDeque`.
105impl<N: ArrayLength> BufRead for GenericArrayDeque<u8, N> {
106  /// Returns the contents of the "front" slice as returned by
107  /// [`as_slices`][`GenericArrayDeque::as_slices`]. If the contained byte slices of the `GenericArrayDeque` are
108  /// discontiguous, multiple calls to `fill_buf` will be needed to read the entire content.
109  #[inline]
110  fn fill_buf(&mut self) -> io::Result<&[u8]> {
111    let (front, _) = self.as_slices();
112    Ok(front)
113  }
114
115  #[inline]
116  fn consume(&mut self, amt: usize) {
117    self.drain(..amt);
118  }
119}
120
121/// Write is implemented for `GenericArrayDeque<u8>` by appending to the `GenericArrayDeque`, growing it as needed.
122impl<N: ArrayLength> Write for GenericArrayDeque<u8, N> {
123  #[inline]
124  fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
125    let remaining = self.remaining_capacity();
126    if remaining == 0 || buf.is_empty() {
127      return Ok(0);
128    }
129
130    self.extend_bytes(buf[..remaining.min(buf.len())].as_ref());
131    Ok(buf.len())
132  }
133
134  #[inline]
135  fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
136    let len = bufs.iter().map(|b| b.len()).sum();
137    if len > self.remaining_capacity() {
138      return Err(io::Error::new(
139        io::ErrorKind::WriteZero,
140        "not enough capacity to write buffer",
141      ));
142    }
143
144    for buf in bufs {
145      self.extend_bytes(buf);
146    }
147    Ok(len)
148  }
149
150  #[inline]
151  fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
152    if buf.len() > self.remaining_capacity() {
153      return Err(io::Error::new(
154        io::ErrorKind::WriteZero,
155        "not enough capacity to write buffer",
156      ));
157    }
158    self.extend_bytes(buf);
159    Ok(())
160  }
161
162  #[inline]
163  fn flush(&mut self) -> io::Result<()> {
164    Ok(())
165  }
166}
167
168trait SplitAt {
169  #[allow(unstable_name_collisions)]
170  fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)>;
171}
172
173trait SplitAtMut {
174  #[allow(unstable_name_collisions)]
175  fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut Self, &mut Self)>;
176}
177
178#[rustversion::since(1.80)]
179impl<T> SplitAt for [T] {
180  #[allow(unstable_name_collisions)]
181  #[cfg_attr(not(tarpaulin), inline(always))]
182  fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)> {
183    <[T]>::split_at_checked(self, mid)
184  }
185}
186
187#[rustversion::before(1.80)]
188impl<T> SplitAt for [T] {
189  #[allow(unstable_name_collisions)]
190  #[cfg_attr(not(tarpaulin), inline(always))]
191  fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)> {
192    use core::slice::from_raw_parts;
193
194    let len = self.len();
195    if mid <= len {
196      // SAFETY: `0 <= mid <= self.len()`
197      Some(unsafe {
198        (
199          from_raw_parts(self.as_ptr(), mid),
200          from_raw_parts(self.as_ptr().add(mid), len - mid),
201        )
202      })
203    } else {
204      None
205    }
206  }
207}
208
209#[rustversion::since(1.80)]
210impl<T> SplitAtMut for [T] {
211  #[allow(unstable_name_collisions)]
212  #[cfg_attr(not(tarpaulin), inline(always))]
213  fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut Self, &mut Self)> {
214    <[T]>::split_at_mut_checked(self, mid)
215  }
216}
217
218#[rustversion::before(1.80)]
219impl<T> SplitAtMut for [T] {
220  #[allow(unstable_name_collisions)]
221  #[cfg_attr(not(tarpaulin), inline(always))]
222  fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut Self, &mut Self)> {
223    use core::slice::from_raw_parts_mut;
224    let len = self.len();
225    if mid <= len {
226      let len = self.len();
227      // SAFETY: `0 <= mid <= self.len()`, so the two slices do not overlap.
228      Some(unsafe {
229        (
230          from_raw_parts_mut(self.as_mut_ptr(), mid),
231          from_raw_parts_mut(self.as_mut_ptr().add(mid), len - mid),
232        )
233      })
234    } else {
235      None
236    }
237  }
238}
239
240#[cfg(test)]
241mod tests {
242  use crate::{
243    typenum::{U2, U4, U6, U8},
244    GenericArrayDeque,
245  };
246  use std::{
247    io::{self, BufRead, IoSlice, Read, Write},
248    string::String,
249    vec::Vec,
250  };
251
252  #[test]
253  fn read_consumes_front_slice() {
254    let mut deque = GenericArrayDeque::<u8, U8>::new();
255    for byte in b"hello" {
256      assert!(deque.push_back(*byte).is_none());
257    }
258
259    let mut buf = [0u8; 3];
260    let read = Read::read(&mut deque, &mut buf).unwrap();
261    assert_eq!(read, 3);
262    assert_eq!(&buf[..read], b"hel");
263    assert_eq!(deque.into_iter().collect::<Vec<_>>(), b"lo".to_vec());
264  }
265
266  #[test]
267  fn read_exact_handles_wrapped_storage() {
268    let mut deque = GenericArrayDeque::<u8, U4>::new();
269    for byte in b"abcd" {
270      assert!(deque.push_back(*byte).is_none());
271    }
272    assert_eq!(deque.pop_front(), Some(b'a'));
273    assert!(deque.push_back(b'e').is_none());
274
275    let mut buf = [0u8; 3];
276    deque.read_exact(&mut buf).unwrap();
277    assert_eq!(&buf, b"bcd");
278    assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![b'e']);
279  }
280
281  #[test]
282  fn read_exact_reports_eof() {
283    let mut deque = GenericArrayDeque::<u8, U4>::new();
284    assert!(deque.push_back(b'x').is_none());
285
286    let mut buf = [0u8; 2];
287    let err = Read::read_exact(&mut deque, &mut buf).unwrap_err();
288    assert_eq!(err.kind(), io::ErrorKind::UnexpectedEof);
289  }
290
291  #[test]
292  fn read_to_end_and_string_clear_buffer() {
293    let mut deque = GenericArrayDeque::<u8, U6>::new();
294    for byte in b"abc" {
295      assert!(deque.push_back(*byte).is_none());
296    }
297    let mut buf = Vec::new();
298    deque.read_to_end(&mut buf).unwrap();
299    assert_eq!(buf, b"abc");
300    assert!(deque.is_empty());
301
302    for byte in b"de" {
303      assert!(deque.push_back(*byte).is_none());
304    }
305    let mut string = String::new();
306    deque.read_to_string(&mut string).unwrap();
307    assert_eq!(string, "de");
308    assert_eq!(deque.len(), 2);
309
310    deque.clear();
311    deque.push_back(0xFF);
312    let mut invalid = String::new();
313    let err = deque.read_to_string(&mut invalid).unwrap_err();
314    assert_eq!(err.kind(), io::ErrorKind::InvalidData);
315  }
316
317  #[test]
318  fn bufread_fill_and_consume() {
319    let mut deque = GenericArrayDeque::<u8, U4>::new();
320    for byte in b"abcd" {
321      assert!(deque.push_back(*byte).is_none());
322    }
323
324    let buf = BufRead::fill_buf(&mut deque).unwrap();
325    assert_eq!(buf, b"abcd");
326    BufRead::consume(&mut deque, 3);
327    assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![b'd']);
328  }
329
330  #[test]
331  fn write_variants_respect_capacity() {
332    let mut deque = GenericArrayDeque::<u8, U4>::new();
333    let written = Write::write(&mut deque, b"abcdef").unwrap();
334    assert_eq!(written, 6);
335    assert_eq!(deque.len(), 4);
336
337    let mut deque = GenericArrayDeque::<u8, U8>::new();
338    let slices = [IoSlice::new(b"ab"), IoSlice::new(b"cd")];
339    assert_eq!(Write::write_vectored(&mut deque, &slices).unwrap(), 4);
340    assert_eq!(deque.len(), 4);
341    let overflow = [IoSlice::new(b"1234"), IoSlice::new(b"5678")];
342    let err = Write::write_vectored(&mut deque, &overflow).unwrap_err();
343    assert_eq!(err.kind(), io::ErrorKind::WriteZero);
344
345    let mut deque = GenericArrayDeque::<u8, U4>::new();
346    Write::write_all(&mut deque, b"wxyz").unwrap();
347    let err = Write::write_all(&mut deque, b"overflow").unwrap_err();
348    assert_eq!(err.kind(), io::ErrorKind::WriteZero);
349
350    let mut deque = GenericArrayDeque::<u8, U2>::new();
351    Write::flush(&mut deque).unwrap();
352  }
353}