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}