buffer_trait/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
9use alloc::boxed::Box;
10#[cfg(feature = "alloc")]
11use alloc::vec::Vec;
12use core::marker::PhantomData;
13use core::mem::MaybeUninit;
14use core::slice;
15
16/// A memory buffer that may be uninitialized.
17///
18/// There are three types that implement the `Buffer` trait, and the type you
19/// use determines the return type of the functions that use it:
20///
21/// | If you pass a…          | You get back a… |
22/// | ----------------------- | --------------- |
23/// | `&mut [T]`              | `usize`, indicating the number of elements initialized. |
24/// | `&mut [MaybeUninit<T>]` | `(&mut [T], &mut [MaybeUninit<T>])`, holding the initialized and uninitialized subslices. |
25/// | [`SpareCapacity`]       | `usize`, indicating the number of elements initialized. And the `Vec` is extended. |
26/// | `&mut`[`Cursor<T, B>`]  | `usize`, indicating the number of elements initialized. And the `Cursor` is advanced. Be sure to call [`Cursor::finish`] when you're done writing to it. |
27///
28/// # Examples
29///
30/// Passing a `&mut [T]`:
31///
32/// ```
33/// # use rustix::io::read;
34/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> {
35/// let mut buf = [0_u8; 64];
36/// let nread = read(fd, &mut buf)?;
37/// // `nread` is the number of bytes read.
38/// # Ok(())
39/// # }
40/// ```
41///
42/// Passing a `&mut [MaybeUninit<T>]`:
43///
44/// ```
45/// # use rustix::io::read;
46/// # use std::mem::MaybeUninit;
47/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> {
48/// let mut buf = [MaybeUninit::<u8>::uninit(); 64];
49/// let (init, uninit) = read(fd, &mut buf)?;
50/// // `init` is a `&mut [u8]` with the initialized bytes.
51/// // `uninit` is a `&mut [MaybeUninit<u8>]` with the remaining bytes.
52/// # Ok(())
53/// # }
54/// ```
55///
56/// Passing a [`SpareCapacity`], via the [`spare_capacity`] helper function:
57///
58/// ```
59/// # use rustix::io::read;
60/// # use rustix::buffer::spare_capacity;
61/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> {
62/// let mut buf = Vec::with_capacity(64);
63/// let nread = read(fd, spare_capacity(&mut buf))?;
64/// // `nread` is the number of bytes read.
65/// // Also, `buf.len()` is now `nread` elements longer than it was before.
66/// # Ok(())
67/// # }
68/// ```
69///
70/// Passing a `&mut`[`Cursor<T, B>`]:
71///
72/// ```no_run,ignore
73/// # use rustix::io::read;
74/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> {
75/// let mut buf = [0_u8; 64];
76/// let mut cursor = Cursor::new(spare_capacity(&mut buf));
77/// let _nread = read(fd, &mut cursor)?;
78/// let _nread = read(fd, &mut cursor)?;
79/// let _nread = read(fd, &mut cursor)?;
80/// let total_nread = cursor.finish();
81/// // `total_nread` is the total number of bytes read.
82/// // Also, `buf.len()` is now `total_nread` bytes longer than it was before.
83/// # Ok(())
84/// # }
85/// ```
86///
87/// # Guide to error messages
88///
89/// Sometimes code using `Buffer` can encounter non-obvious error messages.
90/// Here are some we've encountered, along with ways to fix them.
91///
92/// If you see errors like
93/// "cannot move out of `self` which is behind a mutable reference"
94/// and
95/// "move occurs because `x` has type `&mut [u8]`, which does not implement the `Copy` trait",
96/// replace `x` with `&mut *x`. See `error_buffer_wrapper` in
97/// examples/buffer_errors.rs.
98///
99/// If you see errors like
100/// "type annotations needed"
101/// and
102/// "cannot infer type of the type parameter `Buf` declared on the function `read`",
103/// you may need to change a `&mut []` to `&mut [0_u8; 0]`. See
104/// `error_empty_slice` in examples/buffer_errors.rs.
105///
106/// If you see errors like
107/// "the trait bound `[MaybeUninit<u8>; 1]: Buffer<u8>` is not satisfied",
108/// add a `&mut` to pass the array by reference instead of by value. See
109/// `error_array_by_value` in examples/buffer_errors.rs.
110///
111/// If you see errors like
112/// "cannot move out of `x`, a captured variable in an `FnMut` closure",
113/// try replacing `x` with `&mut *x`, or, if that doesn't work, try moving a
114/// `let` into the closure body. See `error_retry_closure` and
115/// `error_retry_indirect_closure` in examples/buffer_errors.rs.
116///
117/// If you see errors like
118/// "captured variable cannot escape `FnMut` closure body",
119/// use an explicit loop instead of `retry_on_intr`, assuming you're using
120/// that. See `error_retry_closure_uninit` in examples/buffer_errors.rs.
121///
122/// [`&mut Cursor<T, B>`]: crate::Cursor
123pub trait Buffer<T>
124where
125    Self: Sized,
126{
127    /// The type of the value returned by functions with `Buffer` arguments.
128    type Output;
129
130    /// Return the length of the underlying buffer.
131    fn buffer_len(&self) -> usize;
132
133    /// Return a raw mutable pointer to and length of the underlying buffer.
134    ///
135    /// After using this pointer and length to initialize some elements, call
136    /// [`assume_init`] to declare how many were initialized.
137    ///
138    /// [`assume_init`]: Self::assume_init
139    fn parts_mut(&mut self) -> (*mut T, usize);
140
141    /// Assert that `len` elements were written to, and provide a return value.
142    ///
143    /// # Safety
144    ///
145    /// At least the first `len` elements of the buffer must be initialized.
146    unsafe fn assume_init(self, len: usize) -> Self::Output;
147
148    /// Return a `Cursor` for safely writing to the buffer.
149    ///
150    /// Return a `Cursor`. Calling [`finish`] on the cursor returns the
151    /// `Self::Output`.
152    ///
153    /// This is an alternative to `parts_mut`/`assume_init` which allows
154    /// callers to avoid using `unsafe`.
155    ///
156    /// [`finish`]: Cursor::finish
157    fn cursor(self) -> Cursor<T, Self> {
158        Cursor::new(self)
159    }
160}
161
162impl<T> Buffer<T> for &mut [T] {
163    type Output = usize;
164
165    #[inline]
166    fn buffer_len(&self) -> usize {
167        self.len()
168    }
169
170    #[inline]
171    fn parts_mut(&mut self) -> (*mut T, usize) {
172        (self.as_mut_ptr(), self.len())
173    }
174
175    #[inline]
176    unsafe fn assume_init(self, len: usize) -> Self::Output {
177        len
178    }
179}
180
181impl<T, const N: usize> Buffer<T> for &mut [T; N] {
182    type Output = usize;
183
184    #[inline]
185    fn buffer_len(&self) -> usize {
186        N
187    }
188
189    #[inline]
190    fn parts_mut(&mut self) -> (*mut T, usize) {
191        (self.as_mut_ptr(), N)
192    }
193
194    #[inline]
195    unsafe fn assume_init(self, len: usize) -> Self::Output {
196        len
197    }
198}
199
200// `Vec` implements `DerefMut` to `&mut [T]`, however it doesn't get
201// auto-derefed in a `impl Buffer<T>`, so we add this `impl` so that our users
202// don't have to add an extra `*` in these situations.
203#[cfg(feature = "alloc")]
204impl<T> Buffer<T> for &mut Vec<T> {
205    type Output = usize;
206
207    #[inline]
208    fn buffer_len(&self) -> usize {
209        self.len()
210    }
211
212    #[inline]
213    fn parts_mut(&mut self) -> (*mut T, usize) {
214        (self.as_mut_ptr(), self.len())
215    }
216
217    #[inline]
218    unsafe fn assume_init(self, len: usize) -> Self::Output {
219        len
220    }
221}
222
223// Similarly, `Box<[T]>` implements `DerefMut` to `&mut [T]`, however it
224// doesn't get auto-derefed in a `impl Buffer<u8>`, so we add this `impl` so
225// that our users don't have to add an extra `*` in these situations.
226#[cfg(feature = "alloc")]
227impl<T> Buffer<T> for &mut Box<[T]> {
228    type Output = usize;
229
230    #[inline]
231    fn buffer_len(&self) -> usize {
232        self.len()
233    }
234
235    #[inline]
236    fn parts_mut(&mut self) -> (*mut T, usize) {
237        (self.as_mut_ptr(), self.len())
238    }
239
240    #[inline]
241    unsafe fn assume_init(self, len: usize) -> Self::Output {
242        len
243    }
244}
245
246impl<'a, T> Buffer<T> for &'a mut [MaybeUninit<T>] {
247    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
248
249    #[inline]
250    fn buffer_len(&self) -> usize {
251        self.len()
252    }
253
254    #[inline]
255    fn parts_mut(&mut self) -> (*mut T, usize) {
256        (self.as_mut_ptr().cast(), self.len())
257    }
258
259    #[inline]
260    unsafe fn assume_init(self, len: usize) -> Self::Output {
261        // SAFETY: The caller asserts that at least `len` elements of the
262        // buffer have been initialized.
263        unsafe {
264            let (init, uninit) = self.split_at_mut(len);
265
266            // Convert `init` from `&mut [MaybeUninit<T>]` to `&mut [T]`.
267            let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
268
269            (init, uninit)
270        }
271    }
272}
273
274impl<'a, T, const N: usize> Buffer<T> for &'a mut [MaybeUninit<T>; N] {
275    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
276
277    #[inline]
278    fn buffer_len(&self) -> usize {
279        N
280    }
281
282    #[inline]
283    fn parts_mut(&mut self) -> (*mut T, usize) {
284        (self.as_mut_ptr().cast(), N)
285    }
286
287    #[inline]
288    unsafe fn assume_init(self, len: usize) -> Self::Output {
289        // SAFETY: The caller asserts that at least `len` elements of the
290        // buffer have been initialized.
291        unsafe {
292            let (init, uninit) = self.split_at_mut(len);
293
294            // Convert `init` from `&mut [MaybeUninit<T>]` to `&mut [T]`.
295            let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
296
297            (init, uninit)
298        }
299    }
300}
301
302#[cfg(feature = "alloc")]
303impl<'a, T> Buffer<T> for &'a mut Vec<MaybeUninit<T>> {
304    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
305
306    #[inline]
307    fn buffer_len(&self) -> usize {
308        self.len()
309    }
310
311    #[inline]
312    fn parts_mut(&mut self) -> (*mut T, usize) {
313        (self.as_mut_ptr().cast(), self.len())
314    }
315
316    #[inline]
317    unsafe fn assume_init(self, len: usize) -> Self::Output {
318        // SAFETY: The caller asserts that at least `len` elements of the
319        // buffer have been initialized.
320        unsafe {
321            let (init, uninit) = self.split_at_mut(len);
322
323            // Convert `init` from `&mut [MaybeUninit<T>]` to `&mut [T]`.
324            let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
325
326            (init, uninit)
327        }
328    }
329}
330
331#[cfg(feature = "alloc")]
332impl<'a, T> Buffer<T> for &'a mut Box<[MaybeUninit<T>]> {
333    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
334
335    #[inline]
336    fn buffer_len(&self) -> usize {
337        self.len()
338    }
339
340    #[inline]
341    fn parts_mut(&mut self) -> (*mut T, usize) {
342        (self.as_mut_ptr().cast(), self.len())
343    }
344
345    #[inline]
346    unsafe fn assume_init(self, len: usize) -> Self::Output {
347        // SAFETY: The caller asserts that at least `len` elements of the
348        // buffer have been initialized.
349        unsafe {
350            let (init, uninit) = self.split_at_mut(len);
351
352            // Convert `init` from `&mut [MaybeUninit<T>]` to `&mut [T]`.
353            let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
354
355            (init, uninit)
356        }
357    }
358}
359
360/// A type that implements [`Buffer`] by appending to a `Vec`, up to its
361/// capacity.
362///
363/// To use this, use the [`spare_capacity`] function.
364///
365/// Because this uses the capacity, and never reallocates, the `Vec` should
366/// have some non-empty spare capacity.
367#[cfg(feature = "alloc")]
368#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
369pub struct SpareCapacity<'a, T>(&'a mut Vec<T>);
370
371/// Construct a [`SpareCapacity`], which implements [`Buffer`].
372///
373/// This wraps a `&mut Vec` and uses the spare capacity of the `Vec` as the
374/// buffer to receive data in, automatically calling `set_len` on the `Vec` to
375/// set the length to include the received elements.
376///
377/// This uses the existing capacity, and never allocates, so the `Vec` should
378/// have some non-empty spare capacity!
379///
380/// # Examples
381///
382/// ```
383/// # fn test(input: rustix::fd::BorrowedFd) -> rustix::io::Result<()> {
384/// use rustix::buffer::spare_capacity;
385/// use rustix::io::{Errno, read};
386///
387/// let mut buf = Vec::with_capacity(1024);
388/// match read(input, spare_capacity(&mut buf)) {
389///     Ok(0) => { /* end of stream */ }
390///     Ok(n) => { /* `buf` is now `n` bytes longer */ }
391///     Err(Errno::INTR) => { /* `buf` is unmodified */ }
392///     Err(e) => {
393///         return Err(e);
394///     }
395/// }
396///
397/// # Ok(())
398/// # }
399/// ```
400#[cfg(feature = "alloc")]
401#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
402pub fn spare_capacity<'a, T>(v: &'a mut Vec<T>) -> SpareCapacity<'a, T> {
403    debug_assert_ne!(
404        v.capacity(),
405        0,
406        "`extend` uses spare capacity, and never allocates new memory, so the `Vec` passed to it \
407         should have some spare capacity."
408    );
409
410    SpareCapacity(v)
411}
412
413#[cfg(feature = "alloc")]
414impl<'a, T> Buffer<T> for SpareCapacity<'a, T> {
415    /// The number of elements written into the buffer.
416    ///
417    /// This is somewhat redundant, as `set_len` is also called on the
418    /// referenced `Vec`, however it can be convenient in some cases, such as
419    /// for testing for end-of-stream.
420    type Output = usize;
421
422    #[inline]
423    fn buffer_len(&self) -> usize {
424        self.0.capacity() - self.0.len()
425    }
426
427    #[inline]
428    fn parts_mut(&mut self) -> (*mut T, usize) {
429        let spare = self.0.spare_capacity_mut();
430        (spare.as_mut_ptr().cast(), spare.len())
431    }
432
433    #[inline]
434    unsafe fn assume_init(self, len: usize) -> Self::Output {
435        // SAFETY: The caller asserts that at least `len` elements of the spare
436        // capacity region have been initialized.
437        unsafe {
438            self.0.set_len(self.0.len() + len);
439        }
440        len
441    }
442}
443
444/// A cursor for safely writing into an uninitialized buffer.
445///
446/// # Examples
447///
448/// ```ignore
449/// # use buffer_trait::{Cursor, spare_capacity};
450/// let mut buf = Vec::with_capacity(256);
451/// let mut cursor = Cursor::new(spare_capacity(&mut buf));
452/// let _nread = read(&input, &mut cursor).unwrap();
453/// let _nread = read(&input, &mut cursor).unwrap();
454/// let _nread = read(&input, &mut cursor).unwrap();
455/// let total_read = cursor.finish();
456/// ```
457pub struct Cursor<T, B: Buffer<T>> {
458    pos: usize,
459    b: B,
460    phantom: PhantomData<T>,
461}
462
463impl<T, B: Buffer<T>> Cursor<T, B> {
464    /// Construct a new `Cursor`.
465    pub fn new(b: B) -> Self {
466        Self {
467            pos: 0,
468            b,
469            phantom: PhantomData,
470        }
471    }
472
473    /// Return the remaining amount of space in the buffer.
474    pub fn remaining(&self) -> usize {
475        self.b.buffer_len() - self.pos
476    }
477
478    /// Write an element to the buffer.
479    ///
480    /// # Panics
481    ///
482    /// Panics if this cursor has already reached the end of the buffer.
483    pub fn write(&mut self, t: T) {
484        let (ptr, len) = self.b.parts_mut();
485
486        assert!(self.pos < len);
487
488        // SAFETY: `Cursor::new` requires that `ptr` and `len` are valid, and we
489        // just bounds-checked `pos`.
490        unsafe {
491            ptr.add(self.pos).write(t);
492        }
493
494        // Count how many elements we've initialized.
495        self.pos += 1;
496    }
497
498    /// Write multiple elements to the buffer.
499    ///
500    /// # Panics
501    ///
502    /// Panics if this cursor is already within `t.len()` elements of the end
503    /// of the buffer.
504    pub fn write_slice(&mut self, t: &[T])
505    where
506        T: Copy,
507    {
508        let (ptr, len) = self.b.parts_mut();
509
510        assert!(len - self.pos >= t.len());
511
512        // SAFETY: We've required that `T` implements `Copy`, bounds-checked
513        // the length, and `parts_mut()` should have given us a correct pointer
514        // and length.
515        unsafe {
516            core::ptr::copy_nonoverlapping(t.as_ptr(), ptr, t.len());
517        }
518
519        // Count how many elements we've initialized.
520        self.pos += t.len();
521    }
522
523    /// Finish writing to the buffer and return the output value.
524    pub fn finish(self) -> B::Output {
525        // SAFETY: `Cursor` ensures that exactly `pos` elements have been
526        // written.
527        unsafe { self.b.assume_init(self.pos) }
528    }
529}
530
531impl<T, B: Buffer<T>> Buffer<T> for &mut Cursor<T, B> {
532    type Output = usize;
533
534    #[inline]
535    fn buffer_len(&self) -> usize {
536        self.remaining()
537    }
538
539    #[inline]
540    fn parts_mut(&mut self) -> (*mut T, usize) {
541        let parts = self.b.parts_mut();
542        // SAFETY: We ensure that `self.pos` is always within the bounds
543        // of the buffer.
544        unsafe { (parts.0.add(self.pos), parts.1 - self.pos) }
545    }
546
547    #[inline]
548    unsafe fn assume_init(self, len: usize) -> Self::Output {
549        // Count how many elements we've initialized.
550        self.pos += len;
551        len
552    }
553}
554
555#[cfg(test)]
556mod tests {
557    #[allow(unused_imports)]
558    use super::*;
559
560    /// Test type signatures.
561    #[cfg(not(windows))]
562    #[test]
563    fn test_compilation() {
564        use core::mem::MaybeUninit;
565
566        fn read<B: Buffer<u8>>(b: B) -> Result<B::Output, ()> {
567            Ok(b.cursor().finish())
568        }
569
570        let mut buf = vec![0_u8; 3];
571        buf.reserve(32);
572        let _x: usize = read(spare_capacity(&mut buf)).unwrap();
573        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(buf.spare_capacity_mut()).unwrap();
574        let _x: usize = read(&mut buf).unwrap();
575        let _x: usize = read(&mut *buf).unwrap();
576        let _x: usize = read(&mut buf[..]).unwrap();
577        let _x: usize = read(&mut (*buf)[..]).unwrap();
578
579        let mut buf = [0, 0, 0];
580        let _x: usize = read(&mut buf).unwrap();
581        let _x: usize = read(&mut buf[..]).unwrap();
582
583        let mut buf = vec![0, 0, 0];
584        let _x: usize = read(&mut buf).unwrap();
585        let _x: usize = read(&mut buf[..]).unwrap();
586
587        let mut buf = vec![0, 0, 0].into_boxed_slice();
588        let _x: usize = read(&mut buf).unwrap();
589        let _x: usize = read(&mut buf[..]).unwrap();
590
591        let mut buf = [
592            MaybeUninit::uninit(),
593            MaybeUninit::uninit(),
594            MaybeUninit::uninit(),
595        ];
596        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&mut buf).unwrap();
597        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&mut buf[..]).unwrap();
598
599        let mut buf = vec![
600            MaybeUninit::uninit(),
601            MaybeUninit::uninit(),
602            MaybeUninit::uninit(),
603        ];
604        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&mut buf).unwrap();
605        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&mut buf[..]).unwrap();
606
607        let mut buf = vec![
608            MaybeUninit::uninit(),
609            MaybeUninit::uninit(),
610            MaybeUninit::uninit(),
611        ]
612        .into_boxed_slice();
613        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&mut buf).unwrap();
614        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&mut buf[..]).unwrap();
615
616        let mut buf = Cursor::new(&mut buf);
617        let _x: usize = read(&mut buf).unwrap();
618        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = buf.finish();
619    }
620
621    /// Test passing a `&mut [u8]` to `read`.
622    #[cfg(not(windows))]
623    #[test]
624    fn test_slice() {
625        use std::io::{Seek, SeekFrom};
626
627        // We need to obtain input stream with contents that we can compare
628        // against, so open our own source file.
629        let mut input = std::fs::File::open("src/lib.rs").unwrap();
630
631        let mut buf = [0_u8; 64];
632        let nread = read(&input, &mut buf).unwrap();
633        assert_eq!(nread, buf.len());
634        assert_eq!(&buf[..39], b"#![doc = include_str!(\"../README.md\")]\n");
635        input.seek(SeekFrom::End(-1)).unwrap();
636        let nread = read(&input, &mut buf).unwrap();
637        assert_eq!(nread, 1);
638        assert_eq!(buf[0], b'\n');
639        input.seek(SeekFrom::End(0)).unwrap();
640        let nread = read(&input, &mut buf).unwrap();
641        assert_eq!(nread, 0);
642    }
643
644    /// Test passing a `&mut [MaybeUninit<u8>]` to `read`.
645    #[cfg(not(windows))]
646    #[test]
647    fn test_slice_uninit() {
648        use core::mem::MaybeUninit;
649        use std::io::{Seek, SeekFrom};
650
651        // We need to obtain input stream with contents that we can compare
652        // against, so open our own source file.
653        let mut input = std::fs::File::open("src/lib.rs").unwrap();
654
655        let mut buf = [MaybeUninit::<u8>::uninit(); 64];
656        let (init, uninit) = read(&input, &mut buf).unwrap();
657        assert_eq!(uninit.len(), 0);
658        assert_eq!(&init[..39], b"#![doc = include_str!(\"../README.md\")]\n");
659        assert_eq!(init.len(), buf.len());
660        assert_eq!(
661            unsafe { core::mem::transmute::<&mut [MaybeUninit<u8>], &mut [u8]>(&mut buf[..39]) },
662            b"#![doc = include_str!(\"../README.md\")]\n"
663        );
664        input.seek(SeekFrom::End(-1)).unwrap();
665        let (init, uninit) = read(&input, &mut buf).unwrap();
666        assert_eq!(init.len(), 1);
667        assert_eq!(init[0], b'\n');
668        assert_eq!(uninit.len(), buf.len() - 1);
669        input.seek(SeekFrom::End(0)).unwrap();
670        let (init, uninit) = read(&input, &mut buf).unwrap();
671        assert_eq!(init.len(), 0);
672        assert_eq!(uninit.len(), buf.len());
673    }
674
675    /// Test passing a `SpareCapacity` to `read`.
676    #[cfg(not(windows))]
677    #[test]
678    fn test_spare_capacity() {
679        use std::io::{Seek, SeekFrom};
680
681        // We need to obtain input stream with contents that we can compare
682        // against, so open our own source file.
683        let mut input = std::fs::File::open("src/lib.rs").unwrap();
684
685        let mut buf = Vec::with_capacity(64);
686        let nread = read(&input, spare_capacity(&mut buf)).unwrap();
687        assert_eq!(nread, buf.capacity());
688        assert_eq!(nread, buf.len());
689        assert_eq!(&buf[..39], b"#![doc = include_str!(\"../README.md\")]\n");
690        buf.clear();
691        input.seek(SeekFrom::End(-1)).unwrap();
692        let nread = read(&input, spare_capacity(&mut buf)).unwrap();
693        assert_eq!(nread, 1);
694        assert_eq!(buf.len(), 1);
695        assert_eq!(buf[0], b'\n');
696        buf.clear();
697        input.seek(SeekFrom::End(0)).unwrap();
698        let nread = read(&input, spare_capacity(&mut buf)).unwrap();
699        assert_eq!(nread, 0);
700        assert!(buf.is_empty());
701    }
702
703    /// Test passing a `Cursor` to `read`.
704    #[test]
705    fn test_cursor_as_buffer() {
706        use std::io::{Seek, SeekFrom};
707
708        // We need to obtain input stream with contents that we can compare
709        // against, so open our own source file.
710        let mut input = std::fs::File::open("src/lib.rs").unwrap();
711
712        let mut total_read = 0;
713
714        let mut buf = Vec::with_capacity(256);
715        let mut cursor = Cursor::new(spare_capacity(&mut buf));
716        input.seek(SeekFrom::End(-39)).unwrap();
717        let nread = read(&input, &mut cursor).unwrap();
718        total_read += nread;
719        assert_eq!(cursor.remaining(), 256 - 39);
720        input.seek(SeekFrom::End(-39)).unwrap();
721        let nread = read(&input, &mut cursor).unwrap();
722        total_read += nread;
723        assert_eq!(cursor.remaining(), 256 - 39 * 2);
724        input.seek(SeekFrom::End(-39)).unwrap();
725        let nread = read(&input, &mut cursor).unwrap();
726        total_read += nread;
727        assert_eq!(cursor.remaining(), 256 - 39 * 3);
728
729        assert_eq!(total_read, 39 * 3);
730
731        let cursor_read = cursor.finish();
732        assert_eq!(cursor_read, total_read);
733
734        assert_eq!(buf.len(), 39 * 3);
735        assert_eq!(buf.capacity(), 256);
736        assert_eq!(
737            buf,
738            b"// The comment at the end of the file!\n// The comment at the end of the file!\n// The comment at the end of the file!\n"
739        );
740    }
741
742    /// Test nesting `Cursor`s inside of `Cursor`s.
743    #[test]
744    fn test_nesting() {
745        use std::io::{Seek, SeekFrom};
746
747        // We need to obtain input stream with contents that we can compare
748        // against, so open our own source file.
749        let mut input = std::fs::File::open("src/lib.rs").unwrap();
750
751        let mut total_read = 0;
752
753        let mut buf = Vec::with_capacity(256);
754        let mut cursor = Cursor::new(spare_capacity(&mut buf));
755        input.seek(SeekFrom::End(-39)).unwrap();
756        let nread = read(&input, &mut cursor).unwrap();
757        total_read += nread;
758        assert_eq!(cursor.remaining(), 256 - 39);
759        input.seek(SeekFrom::End(-39)).unwrap();
760        let mut nested_cursor = Cursor::new(&mut cursor);
761        let nested_nread = read(&input, &mut nested_cursor).unwrap();
762        assert_eq!(nested_nread, 39);
763        assert_eq!(nested_cursor.remaining(), 256 - 39 * 2);
764        input.seek(SeekFrom::End(-39)).unwrap();
765        let mut nested_nested_cursor = Cursor::new(&mut nested_cursor);
766        let nested_nested_nread = read(&input, &mut nested_nested_cursor).unwrap();
767        assert_eq!(nested_nested_nread, 39);
768        assert_eq!(nested_nested_cursor.remaining(), 256 - 39 * 3);
769        let inner_nread = nested_nested_cursor.finish();
770        assert_eq!(inner_nread, 39);
771        assert_eq!(nested_cursor.remaining(), 256 - 39 * 3);
772        let nread = nested_cursor.finish();
773        total_read += nread;
774
775        assert_eq!(total_read, 39 * 3);
776        assert_eq!(cursor.remaining(), 256 - 39 * 3);
777
778        let cursor_read = cursor.finish();
779        assert_eq!(cursor_read, total_read);
780
781        assert_eq!(buf.len(), 39 * 3);
782        assert_eq!(buf.capacity(), 256);
783        assert_eq!(
784            &buf[..39*3],
785            b"// The comment at the end of the file!\n// The comment at the end of the file!\n// The comment at the end of the file!\n"
786        );
787    }
788
789    /// Test using a `Cursor` to read into a `MaybeUninit` buffer in multiple
790    /// reads, ultimately producing a single initialized slice.
791    #[test]
792    fn test_incremental() {
793        use std::io::{Seek, SeekFrom};
794
795        // We need to obtain input stream with contents that we can compare
796        // against, so open our own source file.
797        let mut input = std::fs::File::open("src/lib.rs").unwrap();
798
799        let mut total_read = 0;
800
801        let mut buf = [MaybeUninit::<u8>::zeroed(); 256];
802        let mut cursor = Cursor::new(&mut buf);
803        input.seek(SeekFrom::End(-39)).unwrap();
804        let nread = read(&input, &mut cursor).unwrap();
805        total_read += nread;
806        assert_eq!(cursor.remaining(), 256 - 39);
807        input.seek(SeekFrom::End(-39)).unwrap();
808        let nread = read(&input, &mut cursor).unwrap();
809        total_read += nread;
810        assert_eq!(cursor.remaining(), 256 - 39 * 2);
811        input.seek(SeekFrom::End(-39)).unwrap();
812        let nread = read(&input, &mut cursor).unwrap();
813        total_read += nread;
814        assert_eq!(cursor.remaining(), 256 - 39 * 3);
815
816        assert_eq!(total_read, 39 * 3);
817
818        let (init, uninit) = cursor.finish();
819        assert_eq!(init.len(), total_read);
820        assert_eq!(uninit.len(), 256 - total_read);
821
822        assert_eq!(
823            init,
824            b"// The comment at the end of the file!\n// The comment at the end of the file!\n// The comment at the end of the file!\n"
825        );
826    }
827
828    fn read<B: Buffer<u8>>(input: &std::fs::File, mut b: B) -> std::io::Result<B::Output> {
829        use std::os::fd::AsRawFd;
830        let parts = b.parts_mut();
831        let n = unsafe { libc::read(input.as_raw_fd(), parts.0.cast(), parts.1) };
832        if n < 0 {
833            Err(std::io::Error::last_os_error())
834        } else {
835            unsafe { Ok(b.assume_init(n as usize)) }
836        }
837    }
838}
839
840// The comment at the end of the file!