Skip to content

Commit

Permalink
More iteration.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Jan 31, 2025
1 parent 28fc958 commit cce9330
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
15 changes: 4 additions & 11 deletions examples/new_read.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
use rustix::buffer::extend;
use rustix::io::read;
use rustix::stdio::stdin;
use std::mem::MaybeUninit;

fn main() {
let buf = vec![0_u8; 3];
let _x: Vec<u8> = read(stdin(), buf).unwrap();

let mut buf = vec![0_u8; 3];
let _x: () = read(stdin(), extend(&mut buf)).unwrap();
let _x: usize = read(stdin(), &mut buf).unwrap();
let _x: usize = read(stdin(), &mut *buf).unwrap();
let _x: usize = read(stdin(), &mut buf[..]).unwrap();
let _x: usize = read(stdin(), &mut (*buf)[..]).unwrap();

let mut buf = [0, 0, 0];
let _x: usize = read(stdin(), &mut buf).unwrap();

let mut buf = [0, 0, 0];
let _x: usize = read(stdin(), &mut buf[..]).unwrap();

let mut buf = [
Expand All @@ -22,12 +21,6 @@ fn main() {
MaybeUninit::uninit(),
];
let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(stdin(), &mut buf).unwrap();

let mut buf = [
MaybeUninit::uninit(),
MaybeUninit::uninit(),
MaybeUninit::uninit(),
];
let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(stdin(), &mut buf[..]).unwrap();

// This is reduced from src/fs/inotify.rs line 177.
Expand Down
33 changes: 25 additions & 8 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ pub trait Buffer<T>: private::Sealed<T> {}
// Implement `Buffer` for all the types that implement `Sealed`.
impl<T> Buffer<T> for &mut [T] {}
impl<T, const N: usize> Buffer<T> for &mut [T; N] {}
#[cfg(feature = "alloc")]
impl<T> Buffer<T> for &mut Vec<T> {}
impl<'a, T> Buffer<T> for &'a mut [MaybeUninit<T>] {}
impl<'a, T, const N: usize> Buffer<T> for &'a mut [MaybeUninit<T>; N] {}
impl<T> Buffer<T> for Vec<T> {}
#[cfg(feature = "alloc")]
impl<'a, T> Buffer<T> for Extend<'a, T> {}

impl<T> private::Sealed<T> for &mut [T] {
type Result = usize;
Expand Down Expand Up @@ -49,6 +51,7 @@ impl<T, const N: usize> private::Sealed<T> for &mut [T; N] {
// `Vec` implements `DerefMut` to `&mut [T]`, however it doesn't get
// auto-derefed in a `impl Buffer<u8>`, so we add this `impl` so that our users
// don't have to add an extra `*` in these situations.
#[cfg(feature = "alloc")]
impl<T> private::Sealed<T> for &mut Vec<T> {
type Result = usize;

Expand Down Expand Up @@ -101,20 +104,34 @@ impl<'a, T, const N: usize> private::Sealed<T> for &'a mut [MaybeUninit<T>; N] {
}
}

/// A type that implements [`Buffer`] by appending to a `Vec`, up to its
/// capacity.
///
/// Because this uses the capacity, and never reallocates, it's a good idea to
/// reserve some space in a `Vec` before using this!
#[cfg(feature = "alloc")]
pub struct Extend<'a, T>(&'a mut Vec<T>);

/// Construct an [`Extend`].
#[cfg(feature = "alloc")]
pub fn extend<T>(v: &mut Vec<T>) -> Extend<T> {
Extend(v)
}

#[cfg(feature = "alloc")]
impl<T> private::Sealed<T> for Vec<T> {
type Result = Vec<T>;
impl<'a, T> private::Sealed<T> for Extend<'a, T> {
/// The mutated `Vec` reflects the number of bytes read.
type Result = ();

#[inline]
fn as_raw_parts_mut(&mut self) -> (*mut T, usize) {
self.clear();
(self.as_mut_ptr(), self.capacity())
let spare = self.0.spare_capacity_mut();
(spare.as_mut_ptr().cast(), spare.len())
}

#[inline]
unsafe fn finish(mut self, len: usize) -> Self::Result {
self.set_len(len);
self
unsafe fn finish(self, len: usize) -> Self::Result {
self.0.set_len(self.0.len() + len);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ extern crate static_assertions;
#[allow(unused_imports)]
mod static_assertions;

// Internal utilities.
mod buffer;
pub mod buffer;
#[cfg(not(windows))]
#[macro_use]
pub(crate) mod cstr;
Expand Down

0 comments on commit cce9330

Please sign in to comment.