Skip to main content

generic_arraydeque/
io.rs

1use core::str::from_utf8;
2use std::io::{self, BufRead, IoSlice, Read, Write};
3
4use super::{ArrayDeque, ArrayLength};
5
6impl<N: ArrayLength> ArrayDeque<u8, N> {
7  #[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 `ArrayDeque<u8>` by consuming bytes from the front of the `ArrayDeque`.
26impl<N: ArrayLength> Read for ArrayDeque<u8, N> {
27  /// Fill `buf` with the contents of the "front" slice as returned by
28  /// [`as_slices`][`ArrayDeque::as_slices`]. If the contained byte slices of the `ArrayDeque` 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          // Leave the buffered data in place — matches `VecDeque`'s
53          // behavior and lets the caller retry or fall back to `read`.
54          return Err(io::Error::new(
55            io::ErrorKind::UnexpectedEof,
56            "failed to fill whole buffer",
57          ));
58        }
59      },
60    }
61
62    self.drain(..buf.len());
63    Ok(())
64  }
65
66  #[inline]
67  fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
68    // The total len is known upfront so we can reserve it in a single call.
69    let len = self.len();
70    buf
71      .try_reserve(len)
72      .map_err(|_| io::ErrorKind::OutOfMemory)?;
73
74    let (front, back) = self.as_slices();
75    buf.extend_from_slice(front);
76    buf.extend_from_slice(back);
77    self.clear();
78    Ok(len)
79  }
80
81  #[inline]
82  fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
83    // A single UTF-8 codepoint may straddle the ring's split point, so
84    // validate the concatenated byte stream rather than each half.
85    // `make_contiguous` reorganizes the physical buffer in place; after it,
86    // `as_slices` returns everything in the front slice.
87    let bytes = self.make_contiguous();
88    let s = match from_utf8(bytes) {
89      Ok(s) => s,
90      Err(_) => {
91        return Err(io::Error::new(
92          io::ErrorKind::InvalidData,
93          "stream did not contain valid UTF-8",
94        ));
95      }
96    };
97
98    buf
99      .try_reserve(s.len())
100      .map_err(|_| io::ErrorKind::OutOfMemory)?;
101
102    let len = s.len();
103    buf.push_str(s);
104    // Match the `Read::read_to_string` contract: the source is consumed.
105    self.clear();
106    Ok(len)
107  }
108}
109
110/// BufRead is implemented for `ArrayDeque<u8>` by reading bytes from the front of the `ArrayDeque`.
111impl<N: ArrayLength> BufRead for ArrayDeque<u8, N> {
112  /// Returns the contents of the "front" slice as returned by
113  /// [`as_slices`][`ArrayDeque::as_slices`]. If the contained byte slices of the `ArrayDeque` are
114  /// discontiguous, multiple calls to `fill_buf` will be needed to read the entire content.
115  #[inline]
116  fn fill_buf(&mut self) -> io::Result<&[u8]> {
117    let (front, _) = self.as_slices();
118    Ok(front)
119  }
120
121  #[inline]
122  fn consume(&mut self, amt: usize) {
123    self.drain(..amt);
124  }
125}
126
127/// Write is implemented for `ArrayDeque<u8>` by appending to the `ArrayDeque`, growing it as needed.
128impl<N: ArrayLength> Write for ArrayDeque<u8, N> {
129  #[inline]
130  fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
131    let remaining = self.remaining_capacity();
132    if remaining == 0 || buf.is_empty() {
133      return Ok(0);
134    }
135
136    let n = remaining.min(buf.len());
137    self.extend_bytes(&buf[..n]);
138    Ok(n)
139  }
140
141  #[inline]
142  fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
143    // Behave like `write` concatenated over the buffers: write as much as
144    // fits and report the actual byte count. Returning `WriteZero` when
145    // the combined length exceeds capacity would be inconsistent with the
146    // scalar `write`, which performs partial writes.
147    let mut written = 0;
148    for buf in bufs {
149      let remaining = self.remaining_capacity();
150      if remaining == 0 {
151        break;
152      }
153      let n = remaining.min(buf.len());
154      if n == 0 {
155        continue;
156      }
157      self.extend_bytes(&buf[..n]);
158      written += n;
159      if n < buf.len() {
160        // Ran out of room mid-buffer; a further `write` would return 0.
161        break;
162      }
163    }
164    Ok(written)
165  }
166
167  #[inline]
168  fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
169    if buf.len() > self.remaining_capacity() {
170      return Err(io::Error::new(
171        io::ErrorKind::WriteZero,
172        "not enough capacity to write buffer",
173      ));
174    }
175    self.extend_bytes(buf);
176    Ok(())
177  }
178
179  #[inline]
180  fn flush(&mut self) -> io::Result<()> {
181    Ok(())
182  }
183}
184
185trait SplitAt {
186  #[allow(unstable_name_collisions)]
187  fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)>;
188}
189
190trait SplitAtMut {
191  #[allow(unstable_name_collisions)]
192  fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut Self, &mut Self)>;
193}
194
195impl<T> SplitAt for [T] {
196  #[allow(unstable_name_collisions)]
197  #[inline(always)]
198  fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)> {
199    <[T]>::split_at_checked(self, mid)
200  }
201}
202
203impl<T> SplitAtMut for [T] {
204  #[allow(unstable_name_collisions)]
205  #[inline(always)]
206  fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut Self, &mut Self)> {
207    <[T]>::split_at_mut_checked(self, mid)
208  }
209}
210
211#[cfg(test)]
212mod tests {
213  use crate::{
214    ArrayDeque,
215    typenum::{U2, U4, U6, U8},
216  };
217  use std::{
218    io::{self, BufRead, IoSlice, Read, Write},
219    string::String,
220    vec::Vec,
221  };
222
223  #[test]
224  fn read_consumes_front_slice() {
225    let mut deque = ArrayDeque::<u8, U8>::new();
226    for byte in b"hello" {
227      assert!(deque.push_back(*byte).is_none());
228    }
229
230    let mut buf = [0u8; 3];
231    let read = Read::read(&mut deque, &mut buf).unwrap();
232    assert_eq!(read, 3);
233    assert_eq!(&buf[..read], b"hel");
234    assert_eq!(deque.into_iter().collect::<Vec<_>>(), b"lo".to_vec());
235  }
236
237  #[test]
238  fn read_exact_handles_wrapped_storage() {
239    let mut deque = ArrayDeque::<u8, U4>::new();
240    for byte in b"abcd" {
241      assert!(deque.push_back(*byte).is_none());
242    }
243    assert_eq!(deque.pop_front(), Some(b'a'));
244    assert!(deque.push_back(b'e').is_none());
245
246    let mut buf = [0u8; 3];
247    deque.read_exact(&mut buf).unwrap();
248    assert_eq!(&buf, b"bcd");
249    assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![b'e']);
250  }
251
252  #[test]
253  fn read_exact_reports_eof() {
254    let mut deque = ArrayDeque::<u8, U4>::new();
255    assert!(deque.push_back(b'x').is_none());
256
257    let mut buf = [0u8; 2];
258    let err = Read::read_exact(&mut deque, &mut buf).unwrap_err();
259    assert_eq!(err.kind(), io::ErrorKind::UnexpectedEof);
260    // The buffered byte must remain in the deque — matches `VecDeque`.
261    assert_eq!(deque.len(), 1);
262    assert_eq!(deque.pop_front(), Some(b'x'));
263  }
264
265  #[test]
266  fn read_to_end_and_string_clear_buffer() {
267    let mut deque = ArrayDeque::<u8, U6>::new();
268    for byte in b"abc" {
269      assert!(deque.push_back(*byte).is_none());
270    }
271    let mut buf = Vec::new();
272    deque.read_to_end(&mut buf).unwrap();
273    assert_eq!(buf, b"abc");
274    assert!(deque.is_empty());
275
276    for byte in b"de" {
277      assert!(deque.push_back(*byte).is_none());
278    }
279    let mut string = String::new();
280    deque.read_to_string(&mut string).unwrap();
281    assert_eq!(string, "de");
282    // `read_to_string` consumes the source, like the `Read` contract demands.
283    assert!(deque.is_empty());
284
285    deque.clear();
286    deque.push_back(0xFF);
287    let mut invalid = String::new();
288    let err = deque.read_to_string(&mut invalid).unwrap_err();
289    assert_eq!(err.kind(), io::ErrorKind::InvalidData);
290  }
291
292  #[test]
293  fn bufread_fill_and_consume() {
294    let mut deque = ArrayDeque::<u8, U4>::new();
295    for byte in b"abcd" {
296      assert!(deque.push_back(*byte).is_none());
297    }
298
299    let buf = BufRead::fill_buf(&mut deque).unwrap();
300    assert_eq!(buf, b"abcd");
301    BufRead::consume(&mut deque, 3);
302    assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![b'd']);
303  }
304
305  #[test]
306  fn write_variants_respect_capacity() {
307    let mut deque = ArrayDeque::<u8, U4>::new();
308    let written = Write::write(&mut deque, b"abcdef").unwrap();
309    assert_eq!(written, 4);
310    assert_eq!(deque.len(), 4);
311
312    let mut deque = ArrayDeque::<u8, U8>::new();
313    let slices = [IoSlice::new(b"ab"), IoSlice::new(b"cd")];
314    assert_eq!(Write::write_vectored(&mut deque, &slices).unwrap(), 4);
315    assert_eq!(deque.len(), 4);
316    // When the combined length exceeds remaining capacity, `write_vectored`
317    // performs a partial write (matching scalar `write`) rather than erroring.
318    let overflow = [IoSlice::new(b"1234"), IoSlice::new(b"5678")];
319    let written = Write::write_vectored(&mut deque, &overflow).unwrap();
320    assert_eq!(written, 4);
321    assert_eq!(deque.len(), 8);
322
323    let mut deque = ArrayDeque::<u8, U4>::new();
324    Write::write_all(&mut deque, b"wxyz").unwrap();
325    let err = Write::write_all(&mut deque, b"overflow").unwrap_err();
326    assert_eq!(err.kind(), io::ErrorKind::WriteZero);
327
328    let mut deque = ArrayDeque::<u8, U2>::new();
329    Write::flush(&mut deque).unwrap();
330  }
331
332  // Regression: previously, `read_to_string` validated front and back slices
333  // independently, so a codepoint whose bytes straddled the ring boundary
334  // was rejected as InvalidData.
335  #[test]
336  fn read_to_string_accepts_utf8_across_ring_boundary() {
337    let mut deque = ArrayDeque::<u8, U4>::new();
338    // Push 3 padding bytes then `é`'s leading byte; rotate head so `é`
339    // ends up split across the physical buffer boundary.
340    for _ in 0..3 {
341      assert!(deque.push_back(b'x').is_none());
342    }
343    assert!(deque.push_back(0xC3).is_none());
344    for _ in 0..3 {
345      deque.pop_front();
346    }
347    assert!(deque.push_back(0xA9).is_none());
348    // Confirm the bytes are actually split (each half is invalid UTF-8 alone).
349    let (front, back) = deque.as_slices();
350    assert_eq!(front, &[0xC3]);
351    assert_eq!(back, &[0xA9]);
352
353    let mut s = String::new();
354    let n = deque.read_to_string(&mut s).unwrap();
355    assert_eq!(n, 2);
356    assert_eq!(s, "é");
357    assert!(deque.is_empty());
358  }
359
360  // Regression: `write_vectored` used to return `WriteZero` when the combined
361  // buffers exceeded remaining capacity, while `write` did partial writes.
362  #[test]
363  fn write_vectored_does_partial_writes() {
364    let mut deque = ArrayDeque::<u8, U4>::new();
365    let slices = [IoSlice::new(b"12"), IoSlice::new(b"345")];
366    let n = Write::write_vectored(&mut deque, &slices).unwrap();
367    assert_eq!(n, 4);
368    assert_eq!(deque.len(), 4);
369    assert_eq!(deque.iter().copied().collect::<Vec<_>>(), b"1234");
370  }
371
372  #[test]
373  fn read_exact_from_front_slice_only() {
374    // Exercise the `split_at_mut_checked` → None arm where `buf` fits entirely
375    // within the front slice.
376    let mut deque = ArrayDeque::<u8, U4>::new();
377    for byte in b"abcd" {
378      assert!(deque.push_back(*byte).is_none());
379    }
380    let mut buf = [0u8; 2];
381    deque.read_exact(&mut buf).unwrap();
382    assert_eq!(&buf, b"ab");
383    assert_eq!(deque.iter().copied().collect::<Vec<_>>(), b"cd");
384  }
385
386  #[test]
387  fn write_on_full_and_empty_buf_returns_zero() {
388    // `remaining == 0` branch.
389    let mut deque = ArrayDeque::<u8, U4>::new();
390    for byte in b"abcd" {
391      assert!(deque.push_back(*byte).is_none());
392    }
393    assert_eq!(Write::write(&mut deque, b"xx").unwrap(), 0);
394
395    // `buf.is_empty()` branch.
396    let mut deque = ArrayDeque::<u8, U4>::new();
397    assert_eq!(Write::write(&mut deque, b"").unwrap(), 0);
398  }
399
400  #[test]
401  fn write_vectored_skips_empty_slices() {
402    // Exercise the `n == 0 { continue }` arm without hitting the full-capacity
403    // break first.
404    let mut deque = ArrayDeque::<u8, U4>::new();
405    let slices = [IoSlice::new(b""), IoSlice::new(b"ab")];
406    let n = Write::write_vectored(&mut deque, &slices).unwrap();
407    assert_eq!(n, 2);
408    assert_eq!(deque.iter().copied().collect::<Vec<_>>(), b"ab");
409  }
410}