1#![allow(unsafe_code)]
4
5#[cfg(feature = "alloc")]
6use alloc::vec::Vec;
7use core::mem::MaybeUninit;
8use core::slice;
9
10#[cfg_attr(
98    rustc_diagnostics,
99    diagnostic::on_unimplemented(
100        message = "rustix does not accept `{Self}` buffers",
101        label = "Unsupported buffer type",
102        note = "only (potentially uninitialized) byte arrays, slices, and Vecs are supported",
103        note = "please read the docs: https://docs.rs/rustix/latest/rustix/buffer/trait.Buffer.html"
104    )
105)]
106pub trait Buffer<T>: private::Sealed<T> {}
107
108impl<T> Buffer<T> for &mut [T] {}
110impl<T, const N: usize> Buffer<T> for &mut [T; N] {}
111#[cfg(feature = "alloc")]
112impl<T> Buffer<T> for &mut Vec<T> {}
113impl<T> Buffer<T> for &mut [MaybeUninit<T>] {}
114impl<T, const N: usize> Buffer<T> for &mut [MaybeUninit<T>; N] {}
115#[cfg(feature = "alloc")]
116impl<T> Buffer<T> for &mut Vec<MaybeUninit<T>> {}
117#[cfg(feature = "alloc")]
118impl<'a, T> Buffer<T> for SpareCapacity<'a, T> {}
119
120impl<T> private::Sealed<T> for &mut [T] {
121    type Output = usize;
122
123    #[inline]
124    fn parts_mut(&mut self) -> (*mut T, usize) {
125        (self.as_mut_ptr(), self.len())
126    }
127
128    #[inline]
129    unsafe fn assume_init(self, len: usize) -> Self::Output {
130        len
131    }
132}
133
134impl<T, const N: usize> private::Sealed<T> for &mut [T; N] {
135    type Output = usize;
136
137    #[inline]
138    fn parts_mut(&mut self) -> (*mut T, usize) {
139        (self.as_mut_ptr(), N)
140    }
141
142    #[inline]
143    unsafe fn assume_init(self, len: usize) -> Self::Output {
144        len
145    }
146}
147
148#[cfg(feature = "alloc")]
152impl<T> private::Sealed<T> for &mut Vec<T> {
153    type Output = usize;
154
155    #[inline]
156    fn parts_mut(&mut self) -> (*mut T, usize) {
157        (self.as_mut_ptr(), self.len())
158    }
159
160    #[inline]
161    unsafe fn assume_init(self, len: usize) -> Self::Output {
162        len
163    }
164}
165
166impl<'a, T> private::Sealed<T> for &'a mut [MaybeUninit<T>] {
167    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
168
169    #[inline]
170    fn parts_mut(&mut self) -> (*mut T, usize) {
171        (self.as_mut_ptr().cast(), self.len())
172    }
173
174    #[inline]
175    unsafe fn assume_init(self, len: usize) -> Self::Output {
176        let (init, uninit) = self.split_at_mut(len);
177
178        let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
180
181        (init, uninit)
182    }
183}
184
185impl<'a, T, const N: usize> private::Sealed<T> for &'a mut [MaybeUninit<T>; N] {
186    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
187
188    #[inline]
189    fn parts_mut(&mut self) -> (*mut T, usize) {
190        (self.as_mut_ptr().cast(), self.len())
191    }
192
193    #[inline]
194    unsafe fn assume_init(self, len: usize) -> Self::Output {
195        let (init, uninit) = self.split_at_mut(len);
196
197        let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
199
200        (init, uninit)
201    }
202}
203
204#[cfg(feature = "alloc")]
205impl<'a, T> private::Sealed<T> for &'a mut Vec<MaybeUninit<T>> {
206    type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]);
207
208    #[inline]
209    fn parts_mut(&mut self) -> (*mut T, usize) {
210        (self.as_mut_ptr().cast(), self.len())
211    }
212
213    #[inline]
214    unsafe fn assume_init(self, len: usize) -> Self::Output {
215        let (init, uninit) = self.split_at_mut(len);
216
217        let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len());
219
220        (init, uninit)
221    }
222}
223
224#[cfg(feature = "alloc")]
232#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
233pub struct SpareCapacity<'a, T>(&'a mut Vec<T>);
234
235#[cfg(feature = "alloc")]
265#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
266pub fn spare_capacity<'a, T>(v: &'a mut Vec<T>) -> SpareCapacity<'a, T> {
267    debug_assert_ne!(
268        v.capacity(),
269        0,
270        "`extend` uses spare capacity, and never allocates new memory, so the `Vec` passed to it \
271         should have some spare capacity."
272    );
273
274    SpareCapacity(v)
275}
276
277#[cfg(feature = "alloc")]
278impl<'a, T> private::Sealed<T> for SpareCapacity<'a, T> {
279    type Output = usize;
283
284    #[inline]
285    fn parts_mut(&mut self) -> (*mut T, usize) {
286        let spare = self.0.spare_capacity_mut();
287        (spare.as_mut_ptr().cast(), spare.len())
288    }
289
290    #[inline]
291    unsafe fn assume_init(self, len: usize) -> Self::Output {
292        self.0.set_len(self.0.len() + len);
294        len
295    }
296}
297
298mod private {
299    pub trait Sealed<T> {
300        type Output;
302
303        fn parts_mut(&mut self) -> (*mut T, usize);
314
315        #[must_use]
321        unsafe fn assume_init(self, len: usize) -> Self::Output;
322    }
323}
324
325#[cfg(test)]
326mod tests {
327    #[allow(unused_imports)]
328    use super::*;
329
330    #[cfg(not(windows))]
331    #[test]
332    fn test_compilation() {
333        use crate::io::read;
334        use core::mem::MaybeUninit;
335
336        let input = std::fs::File::open("src/buffer.rs").unwrap();
338
339        let mut buf = vec![0_u8; 3];
340        buf.reserve(32);
341        let _x: usize = read(&input, spare_capacity(&mut buf)).unwrap();
342        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) =
343            read(&input, buf.spare_capacity_mut()).unwrap();
344        let _x: usize = read(&input, &mut buf).unwrap();
345        let _x: usize = read(&input, &mut *buf).unwrap();
346        let _x: usize = read(&input, &mut buf[..]).unwrap();
347        let _x: usize = read(&input, &mut (*buf)[..]).unwrap();
348
349        let mut buf = [0, 0, 0];
350        let _x: usize = read(&input, &mut buf).unwrap();
351        let _x: usize = read(&input, &mut buf[..]).unwrap();
352
353        let mut buf = [
354            MaybeUninit::uninit(),
355            MaybeUninit::uninit(),
356            MaybeUninit::uninit(),
357        ];
358        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf).unwrap();
359        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf[..]).unwrap();
360
361        let mut buf = vec![
362            MaybeUninit::uninit(),
363            MaybeUninit::uninit(),
364            MaybeUninit::uninit(),
365        ];
366        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf).unwrap();
367        let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf[..]).unwrap();
368    }
369
370    #[cfg(not(windows))]
371    #[test]
372    fn test_slice() {
373        use crate::io::read;
374        use std::io::{Seek, SeekFrom};
375
376        let mut input = std::fs::File::open("src/buffer.rs").unwrap();
379
380        let mut buf = [0_u8; 64];
381        let nread = read(&input, &mut buf).unwrap();
382        assert_eq!(nread, buf.len());
383        assert_eq!(
384            &buf[..58],
385            b"//! Utilities for functions that return data via buffers.\n"
386        );
387        input.seek(SeekFrom::End(-1)).unwrap();
388        let nread = read(&input, &mut buf).unwrap();
389        assert_eq!(nread, 1);
390        input.seek(SeekFrom::End(0)).unwrap();
391        let nread = read(&input, &mut buf).unwrap();
392        assert_eq!(nread, 0);
393    }
394
395    #[cfg(not(windows))]
396    #[test]
397    fn test_slice_uninit() {
398        use crate::io::read;
399        use core::mem::MaybeUninit;
400        use std::io::{Seek, SeekFrom};
401
402        let mut input = std::fs::File::open("src/buffer.rs").unwrap();
405
406        let mut buf = [MaybeUninit::<u8>::uninit(); 64];
407        let (init, uninit) = read(&input, &mut buf).unwrap();
408        assert_eq!(uninit.len(), 0);
409        assert_eq!(
410            &init[..58],
411            b"//! Utilities for functions that return data via buffers.\n"
412        );
413        assert_eq!(init.len(), buf.len());
414        assert_eq!(
415            unsafe { core::mem::transmute::<&mut [MaybeUninit<u8>], &mut [u8]>(&mut buf[..58]) },
416            b"//! Utilities for functions that return data via buffers.\n"
417        );
418        input.seek(SeekFrom::End(-1)).unwrap();
419        let (init, uninit) = read(&input, &mut buf).unwrap();
420        assert_eq!(init.len(), 1);
421        assert_eq!(uninit.len(), buf.len() - 1);
422        input.seek(SeekFrom::End(0)).unwrap();
423        let (init, uninit) = read(&input, &mut buf).unwrap();
424        assert_eq!(init.len(), 0);
425        assert_eq!(uninit.len(), buf.len());
426    }
427
428    #[cfg(not(windows))]
429    #[test]
430    fn test_spare_capacity() {
431        use crate::io::read;
432        use std::io::{Seek, SeekFrom};
433
434        let mut input = std::fs::File::open("src/buffer.rs").unwrap();
437
438        let mut buf = Vec::with_capacity(64);
439        let nread = read(&input, spare_capacity(&mut buf)).unwrap();
440        assert_eq!(nread, buf.capacity());
441        assert_eq!(nread, buf.len());
442        assert_eq!(
443            &buf[..58],
444            b"//! Utilities for functions that return data via buffers.\n"
445        );
446        buf.clear();
447        input.seek(SeekFrom::End(-1)).unwrap();
448        let nread = read(&input, spare_capacity(&mut buf)).unwrap();
449        assert_eq!(nread, 1);
450        assert_eq!(buf.len(), 1);
451        buf.clear();
452        input.seek(SeekFrom::End(0)).unwrap();
453        let nread = read(&input, spare_capacity(&mut buf)).unwrap();
454        assert_eq!(nread, 0);
455        assert!(buf.is_empty());
456    }
457}