diff --git a/library/core/src/io/cursor.rs b/library/core/src/io/cursor.rs new file mode 100644 index 0000000000000..ebbec6c5e8210 --- /dev/null +++ b/library/core/src/io/cursor.rs @@ -0,0 +1,291 @@ +/// A `Cursor` wraps an in-memory buffer and provides it with a +/// [`Seek`] implementation. +/// +/// `Cursor`s are used with in-memory buffers, anything implementing +/// [AsRef]<\[u8]>, to allow them to implement [`Read`] and/or [`Write`], +/// allowing these buffers to be used anywhere you might use a reader or writer +/// that does actual I/O. +/// +/// The standard library implements some I/O traits on various types which +/// are commonly used as a buffer, like Cursor<[Vec]\> and +/// Cursor<[&\[u8\]][bytes]>. +/// +/// # Examples +/// +/// We may want to write bytes to a [`File`] in our production +/// code, but use an in-memory buffer in our tests. We can do this with +/// `Cursor`: +/// +/// [bytes]: crate::slice "slice" +/// [`File`]: ../../std/fs/struct.File.html +/// [`Read`]: ../../std/io/trait.Read.html +/// [`Write`]: ../../std/io/trait.Write.html +/// [`Seek`]: ../../std/io/trait.Seek.html +/// [Vec]: ../../alloc/vec/struct.Vec.html +/// +/// ```no_run +/// use std::io::prelude::*; +/// use std::io::{self, SeekFrom}; +/// use std::fs::File; +/// +/// // a library function we've written +/// fn write_ten_bytes_at_end(mut writer: W) -> io::Result<()> { +/// writer.seek(SeekFrom::End(-10))?; +/// +/// for i in 0..10 { +/// writer.write(&[i])?; +/// } +/// +/// // all went well +/// Ok(()) +/// } +/// +/// # fn foo() -> io::Result<()> { +/// // Here's some code that uses this library function. +/// // +/// // We might want to use a BufReader here for efficiency, but let's +/// // keep this example focused. +/// let mut file = File::create("foo.txt")?; +/// // First, we need to allocate 10 bytes to be able to write into. +/// file.set_len(10)?; +/// +/// write_ten_bytes_at_end(&mut file)?; +/// # Ok(()) +/// # } +/// +/// // now let's write a test +/// #[test] +/// fn test_writes_bytes() { +/// // setting up a real File is much slower than an in-memory buffer, +/// // let's use a cursor instead +/// use std::io::Cursor; +/// let mut buff = Cursor::new(vec![0; 15]); +/// +/// write_ten_bytes_at_end(&mut buff).unwrap(); +/// +/// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Debug, Default, Eq, PartialEq)] +pub struct Cursor { + inner: T, + pos: u64, +} + +impl Cursor { + /// Creates a new cursor wrapping the provided underlying in-memory buffer. + /// + /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`]) + /// is not empty. So writing to cursor starts with overwriting [`Vec`] + /// content, not with appending to it. + /// + /// [`Vec`]: ../../alloc/vec/struct.Vec.html + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] + pub const fn new(inner: T) -> Cursor { + Cursor { pos: 0, inner } + } + + /// Consumes this cursor, returning the underlying value. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let vec = buff.into_inner(); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn into_inner(self) -> T { + self.inner + } + + /// Gets a reference to the underlying value in this cursor. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let reference = buff.get_ref(); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] + pub const fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying value in this cursor. + /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying value as it may corrupt this cursor's position. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let reference = buff.get_mut(); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")] + pub const fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Returns the current position of this cursor. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// use std::io::prelude::*; + /// use std::io::SeekFrom; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.position(), 0); + /// + /// buff.seek(SeekFrom::Current(2)).unwrap(); + /// assert_eq!(buff.position(), 2); + /// + /// buff.seek(SeekFrom::Current(-1)).unwrap(); + /// assert_eq!(buff.position(), 1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] + pub const fn position(&self) -> u64 { + self.pos + } + + /// Sets the position of this cursor. + /// + /// # Examples + /// + /// ``` + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.position(), 0); + /// + /// buff.set_position(2); + /// assert_eq!(buff.position(), 2); + /// + /// buff.set_position(4); + /// assert_eq!(buff.position(), 4); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")] + pub const fn set_position(&mut self, pos: u64) { + self.pos = pos; + } + + #[doc(hidden)] + #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")] + #[inline] + pub const fn into_parts_mut(&mut self) -> (&mut u64, &mut T) { + (&mut self.pos, &mut self.inner) + } +} + +impl Cursor +where + T: AsRef<[u8]>, +{ + /// Splits the underlying slice at the cursor position and returns them. + /// + /// # Examples + /// + /// ``` + /// #![feature(cursor_split)] + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.split(), ([].as_slice(), [1, 2, 3, 4, 5].as_slice())); + /// + /// buff.set_position(2); + /// assert_eq!(buff.split(), ([1, 2].as_slice(), [3, 4, 5].as_slice())); + /// + /// buff.set_position(6); + /// assert_eq!(buff.split(), ([1, 2, 3, 4, 5].as_slice(), [].as_slice())); + /// ``` + #[unstable(feature = "cursor_split", issue = "86369")] + pub fn split(&self) -> (&[u8], &[u8]) { + let slice = self.inner.as_ref(); + let pos = self.pos.min(slice.len() as u64); + slice.split_at(pos as usize) + } +} + +impl Cursor +where + T: AsMut<[u8]>, +{ + /// Splits the underlying slice at the cursor position and returns them + /// mutably. + /// + /// # Examples + /// + /// ``` + /// #![feature(cursor_split)] + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.split_mut(), ([].as_mut_slice(), [1, 2, 3, 4, 5].as_mut_slice())); + /// + /// buff.set_position(2); + /// assert_eq!(buff.split_mut(), ([1, 2].as_mut_slice(), [3, 4, 5].as_mut_slice())); + /// + /// buff.set_position(6); + /// assert_eq!(buff.split_mut(), ([1, 2, 3, 4, 5].as_mut_slice(), [].as_mut_slice())); + /// ``` + #[unstable(feature = "cursor_split", issue = "86369")] + pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) { + let slice = self.inner.as_mut(); + let pos = self.pos.min(slice.len() as u64); + slice.split_at_mut(pos as usize) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for Cursor +where + T: Clone, +{ + #[inline] + fn clone(&self) -> Self { + Cursor { inner: self.inner.clone(), pos: self.pos } + } + + #[inline] + fn clone_from(&mut self, other: &Self) { + self.inner.clone_from(&other.inner); + self.pos = other.pos; + } +} diff --git a/library/core/src/io/mod.rs b/library/core/src/io/mod.rs index 2d8273dd1b2d0..333e436ddb573 100644 --- a/library/core/src/io/mod.rs +++ b/library/core/src/io/mod.rs @@ -1,11 +1,14 @@ //! Traits, helpers, and type definitions for core I/O functionality. mod borrowed_buf; +mod cursor; mod error; #[unstable(feature = "core_io_borrowed_buf", issue = "117693")] pub use self::borrowed_buf::{BorrowedBuf, BorrowedCursor}; #[unstable(feature = "core_io", issue = "154046")] +pub use self::cursor::Cursor; +#[unstable(feature = "core_io", issue = "154046")] pub use self::error::ErrorKind; #[unstable(feature = "raw_os_error_ty", issue = "107792")] pub use self::error::RawOsError; diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index d7131e2fe92fd..9cd6d013f472c 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -1,290 +1,14 @@ #[cfg(test)] mod tests; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::io::Cursor; + use crate::alloc::Allocator; use crate::cmp; use crate::io::prelude::*; use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; -/// A `Cursor` wraps an in-memory buffer and provides it with a -/// [`Seek`] implementation. -/// -/// `Cursor`s are used with in-memory buffers, anything implementing -/// [AsRef]<\[u8]>, to allow them to implement [`Read`] and/or [`Write`], -/// allowing these buffers to be used anywhere you might use a reader or writer -/// that does actual I/O. -/// -/// The standard library implements some I/O traits on various types which -/// are commonly used as a buffer, like Cursor<[Vec]\> and -/// Cursor<[&\[u8\]][bytes]>. -/// -/// # Examples -/// -/// We may want to write bytes to a [`File`] in our production -/// code, but use an in-memory buffer in our tests. We can do this with -/// `Cursor`: -/// -/// [bytes]: crate::slice "slice" -/// [`File`]: crate::fs::File -/// -/// ```no_run -/// use std::io::prelude::*; -/// use std::io::{self, SeekFrom}; -/// use std::fs::File; -/// -/// // a library function we've written -/// fn write_ten_bytes_at_end(mut writer: W) -> io::Result<()> { -/// writer.seek(SeekFrom::End(-10))?; -/// -/// for i in 0..10 { -/// writer.write(&[i])?; -/// } -/// -/// // all went well -/// Ok(()) -/// } -/// -/// # fn foo() -> io::Result<()> { -/// // Here's some code that uses this library function. -/// // -/// // We might want to use a BufReader here for efficiency, but let's -/// // keep this example focused. -/// let mut file = File::create("foo.txt")?; -/// // First, we need to allocate 10 bytes to be able to write into. -/// file.set_len(10)?; -/// -/// write_ten_bytes_at_end(&mut file)?; -/// # Ok(()) -/// # } -/// -/// // now let's write a test -/// #[test] -/// fn test_writes_bytes() { -/// // setting up a real File is much slower than an in-memory buffer, -/// // let's use a cursor instead -/// use std::io::Cursor; -/// let mut buff = Cursor::new(vec![0; 15]); -/// -/// write_ten_bytes_at_end(&mut buff).unwrap(); -/// -/// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); -/// } -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug, Default, Eq, PartialEq)] -pub struct Cursor { - inner: T, - pos: u64, -} - -impl Cursor { - /// Creates a new cursor wrapping the provided underlying in-memory buffer. - /// - /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`]) - /// is not empty. So writing to cursor starts with overwriting [`Vec`] - /// content, not with appending to it. - /// - /// # Examples - /// - /// ``` - /// use std::io::Cursor; - /// - /// let buff = Cursor::new(Vec::new()); - /// # fn force_inference(_: &Cursor>) {} - /// # force_inference(&buff); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] - pub const fn new(inner: T) -> Cursor { - Cursor { pos: 0, inner } - } - - /// Consumes this cursor, returning the underlying value. - /// - /// # Examples - /// - /// ``` - /// use std::io::Cursor; - /// - /// let buff = Cursor::new(Vec::new()); - /// # fn force_inference(_: &Cursor>) {} - /// # force_inference(&buff); - /// - /// let vec = buff.into_inner(); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn into_inner(self) -> T { - self.inner - } - - /// Gets a reference to the underlying value in this cursor. - /// - /// # Examples - /// - /// ``` - /// use std::io::Cursor; - /// - /// let buff = Cursor::new(Vec::new()); - /// # fn force_inference(_: &Cursor>) {} - /// # force_inference(&buff); - /// - /// let reference = buff.get_ref(); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] - pub const fn get_ref(&self) -> &T { - &self.inner - } - - /// Gets a mutable reference to the underlying value in this cursor. - /// - /// Care should be taken to avoid modifying the internal I/O state of the - /// underlying value as it may corrupt this cursor's position. - /// - /// # Examples - /// - /// ``` - /// use std::io::Cursor; - /// - /// let mut buff = Cursor::new(Vec::new()); - /// # fn force_inference(_: &Cursor>) {} - /// # force_inference(&buff); - /// - /// let reference = buff.get_mut(); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")] - pub const fn get_mut(&mut self) -> &mut T { - &mut self.inner - } - - /// Returns the current position of this cursor. - /// - /// # Examples - /// - /// ``` - /// use std::io::Cursor; - /// use std::io::prelude::*; - /// use std::io::SeekFrom; - /// - /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); - /// - /// assert_eq!(buff.position(), 0); - /// - /// buff.seek(SeekFrom::Current(2)).unwrap(); - /// assert_eq!(buff.position(), 2); - /// - /// buff.seek(SeekFrom::Current(-1)).unwrap(); - /// assert_eq!(buff.position(), 1); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] - pub const fn position(&self) -> u64 { - self.pos - } - - /// Sets the position of this cursor. - /// - /// # Examples - /// - /// ``` - /// use std::io::Cursor; - /// - /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); - /// - /// assert_eq!(buff.position(), 0); - /// - /// buff.set_position(2); - /// assert_eq!(buff.position(), 2); - /// - /// buff.set_position(4); - /// assert_eq!(buff.position(), 4); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")] - pub const fn set_position(&mut self, pos: u64) { - self.pos = pos; - } -} - -impl Cursor -where - T: AsRef<[u8]>, -{ - /// Splits the underlying slice at the cursor position and returns them. - /// - /// # Examples - /// - /// ``` - /// #![feature(cursor_split)] - /// use std::io::Cursor; - /// - /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); - /// - /// assert_eq!(buff.split(), ([].as_slice(), [1, 2, 3, 4, 5].as_slice())); - /// - /// buff.set_position(2); - /// assert_eq!(buff.split(), ([1, 2].as_slice(), [3, 4, 5].as_slice())); - /// - /// buff.set_position(6); - /// assert_eq!(buff.split(), ([1, 2, 3, 4, 5].as_slice(), [].as_slice())); - /// ``` - #[unstable(feature = "cursor_split", issue = "86369")] - pub fn split(&self) -> (&[u8], &[u8]) { - let slice = self.inner.as_ref(); - let pos = self.pos.min(slice.len() as u64); - slice.split_at(pos as usize) - } -} - -impl Cursor -where - T: AsMut<[u8]>, -{ - /// Splits the underlying slice at the cursor position and returns them - /// mutably. - /// - /// # Examples - /// - /// ``` - /// #![feature(cursor_split)] - /// use std::io::Cursor; - /// - /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); - /// - /// assert_eq!(buff.split_mut(), ([].as_mut_slice(), [1, 2, 3, 4, 5].as_mut_slice())); - /// - /// buff.set_position(2); - /// assert_eq!(buff.split_mut(), ([1, 2].as_mut_slice(), [3, 4, 5].as_mut_slice())); - /// - /// buff.set_position(6); - /// assert_eq!(buff.split_mut(), ([1, 2, 3, 4, 5].as_mut_slice(), [].as_mut_slice())); - /// ``` - #[unstable(feature = "cursor_split", issue = "86369")] - pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) { - let slice = self.inner.as_mut(); - let pos = self.pos.min(slice.len() as u64); - slice.split_at_mut(pos as usize) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Cursor -where - T: Clone, -{ - #[inline] - fn clone(&self) -> Self { - Cursor { inner: self.inner.clone(), pos: self.pos } - } - - #[inline] - fn clone_from(&mut self, other: &Self) { - self.inner.clone_from(&other.inner); - self.pos = other.pos; - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor where @@ -293,16 +17,16 @@ where fn seek(&mut self, style: SeekFrom) -> io::Result { let (base_pos, offset) = match style { SeekFrom::Start(n) => { - self.pos = n; + self.set_position(n); return Ok(n); } - SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), - SeekFrom::Current(n) => (self.pos, n), + SeekFrom::End(n) => (self.get_ref().as_ref().len() as u64, n), + SeekFrom::Current(n) => (self.position(), n), }; match base_pos.checked_add_signed(offset) { Some(n) => { - self.pos = n; - Ok(self.pos) + self.set_position(n); + Ok(n) } None => Err(io::const_error!( ErrorKind::InvalidInput, @@ -312,11 +36,11 @@ where } fn stream_len(&mut self) -> io::Result { - Ok(self.inner.as_ref().len() as u64) + Ok(self.get_ref().as_ref().len() as u64) } fn stream_position(&mut self) -> io::Result { - Ok(self.pos) + Ok(self.position()) } } @@ -327,7 +51,7 @@ where { fn read(&mut self, buf: &mut [u8]) -> io::Result { let n = Read::read(&mut Cursor::split(self).1, buf)?; - self.pos += n as u64; + self.set_position(self.position() + n as u64); Ok(n) } @@ -336,7 +60,7 @@ where Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?; - self.pos += (cursor.written() - prev_written) as u64; + self.set_position(self.position() + (cursor.written() - prev_written) as u64); Ok(()) } @@ -361,9 +85,9 @@ where let result = Read::read_exact(&mut Cursor::split(self).1, buf); match result { - Ok(_) => self.pos += buf.len() as u64, + Ok(_) => self.set_position(self.position() + buf.len() as u64), // The only possible error condition is EOF, so place the cursor at "EOF" - Err(_) => self.pos = self.inner.as_ref().len() as u64, + Err(_) => self.set_position(self.get_ref().as_ref().len() as u64), } result @@ -373,7 +97,7 @@ where let prev_written = cursor.written(); let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow()); - self.pos += (cursor.written() - prev_written) as u64; + self.set_position(self.position() + (cursor.written() - prev_written) as u64); result } @@ -383,7 +107,7 @@ where let len = content.len(); buf.try_reserve(len)?; buf.extend_from_slice(content); - self.pos += len as u64; + self.set_position(self.position() + len as u64); Ok(len) } @@ -394,7 +118,7 @@ where let len = content.len(); buf.try_reserve(len)?; buf.push_str(content); - self.pos += len as u64; + self.set_position(self.position() + len as u64); Ok(len) } @@ -409,7 +133,7 @@ where Ok(Cursor::split(self).1) } fn consume(&mut self, amt: usize) { - self.pos += amt as u64; + self.set_position(self.position() + amt as u64); } } @@ -590,12 +314,14 @@ where impl Write for Cursor<&mut [u8]> { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { - slice_write(&mut self.pos, self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + slice_write(pos, inner, buf) } #[inline] fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - slice_write_vectored(&mut self.pos, self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + slice_write_vectored(pos, inner, bufs) } #[inline] @@ -605,12 +331,14 @@ impl Write for Cursor<&mut [u8]> { #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - slice_write_all(&mut self.pos, self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + slice_write_all(pos, inner, buf) } #[inline] fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - slice_write_all_vectored(&mut self.pos, self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + slice_write_all_vectored(pos, inner, bufs) } #[inline] @@ -625,11 +353,13 @@ where A: Allocator, { fn write(&mut self, buf: &[u8]) -> io::Result { - vec_write_all(&mut self.pos, self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + vec_write_all(pos, inner, buf) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - vec_write_all_vectored(&mut self.pos, self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + vec_write_all_vectored(pos, inner, bufs) } #[inline] @@ -638,12 +368,14 @@ where } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - vec_write_all(&mut self.pos, self.inner, buf)?; + let (pos, inner) = self.into_parts_mut(); + vec_write_all(pos, inner, buf)?; Ok(()) } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - vec_write_all_vectored(&mut self.pos, self.inner, bufs)?; + let (pos, inner) = self.into_parts_mut(); + vec_write_all_vectored(pos, inner, bufs)?; Ok(()) } @@ -659,11 +391,13 @@ where A: Allocator, { fn write(&mut self, buf: &[u8]) -> io::Result { - vec_write_all(&mut self.pos, &mut self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + vec_write_all(pos, inner, buf) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + vec_write_all_vectored(pos, inner, bufs) } #[inline] @@ -672,12 +406,14 @@ where } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - vec_write_all(&mut self.pos, &mut self.inner, buf)?; + let (pos, inner) = self.into_parts_mut(); + vec_write_all(pos, inner, buf)?; Ok(()) } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)?; + let (pos, inner) = self.into_parts_mut(); + vec_write_all_vectored(pos, inner, bufs)?; Ok(()) } @@ -694,12 +430,14 @@ where { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { - slice_write(&mut self.pos, &mut self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + slice_write(pos, inner, buf) } #[inline] fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - slice_write_vectored(&mut self.pos, &mut self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + slice_write_vectored(pos, inner, bufs) } #[inline] @@ -709,12 +447,14 @@ where #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - slice_write_all(&mut self.pos, &mut self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + slice_write_all(pos, inner, buf) } #[inline] fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + slice_write_all_vectored(pos, inner, bufs) } #[inline] @@ -727,12 +467,14 @@ where impl Write for Cursor<[u8; N]> { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { - slice_write(&mut self.pos, &mut self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + slice_write(pos, inner, buf) } #[inline] fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { - slice_write_vectored(&mut self.pos, &mut self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + slice_write_vectored(pos, inner, bufs) } #[inline] @@ -742,12 +484,14 @@ impl Write for Cursor<[u8; N]> { #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - slice_write_all(&mut self.pos, &mut self.inner, buf) + let (pos, inner) = self.into_parts_mut(); + slice_write_all(pos, inner, buf) } #[inline] fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs) + let (pos, inner) = self.into_parts_mut(); + slice_write_all_vectored(pos, inner, bufs) } #[inline] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index bb280f698b852..f20d1d72d22cb 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -326,6 +326,7 @@ #![feature(core_io_borrowed_buf)] #![feature(core_io_internals)] #![feature(cstr_display)] +#![feature(cursor_split)] #![feature(drop_guard)] #![feature(duration_constants)] #![feature(error_generic_member_access)]