From db5d697004d8bf3ce783d02f2e4a1c8354281d78 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 3 Dec 2020 20:13:51 +0000 Subject: [PATCH 1/3] std: impl of `Write` for `&mut [u8]`: document the buffer full error Signed-off-by: Ian Jackson --- library/std/src/io/impls.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index 6b3c86cb0df87..00bf8b9af7384 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -306,6 +306,10 @@ impl BufRead for &[u8] { /// /// Note that writing updates the slice to point to the yet unwritten part. /// The slice will be empty when it has been completely overwritten. +/// +/// If the number of bytes to be written exceeds the size of the slice, write operations will +/// return short writes: ultimately, `Ok(0)`; in this situation, `write_all` returns an error of +/// kind `ErrorKind::WriteZero`. #[stable(feature = "rust1", since = "1.0.0")] impl Write for &mut [u8] { #[inline] From 19c7619dcda902acafa927b0b8511ca8ecce13a4 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 2 Nov 2020 20:58:12 +0000 Subject: [PATCH 2/3] IntoInnerError: Provide into_parts In particular, IntoIneerError only currently provides .error() which returns a reference, not an owned value. This is not helpful and means that a caller of BufWriter::into_inner cannot acquire an owned io::Error which seems quite wrong. Signed-off-by: Ian Jackson --- library/std/src/io/buffered/mod.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/std/src/io/buffered/mod.rs b/library/std/src/io/buffered/mod.rs index f9caeaf98e2fb..0b58e55ed1731 100644 --- a/library/std/src/io/buffered/mod.rs +++ b/library/std/src/io/buffered/mod.rs @@ -126,6 +126,30 @@ impl IntoInnerError { pub fn into_inner(self) -> W { self.0 } + + /// Consumes the [`IntoInnerError`] and returns the error which caused the call to + /// [`BufWriter::into_inner()`] to fail, and the underlying writer. + /// + /// This can be used to simply obtain ownership of the underlying error; it can also be used for + /// advanced error recovery. + /// + /// # Example + /// ``` + /// #![feature(io_into_inner_error_parts)] + /// use std::io::{BufWriter, ErrorKind, Write}; + /// + /// let mut not_enough_space = [0u8; 10]; + /// let mut stream = BufWriter::new(not_enough_space.as_mut()); + /// write!(stream, "this cannot be actually written").unwrap(); + /// let into_inner_err = stream.into_inner().expect_err("now we discover it's too small"); + /// let (err, recovered_writer) = into_inner_err.into_parts(); + /// assert_eq!(err.kind(), ErrorKind::WriteZero); + /// assert_eq!(recovered_writer.buffer(), b"t be actually written"); + /// ``` + #[unstable(feature = "io_into_inner_error_parts", issue = "79704")] + pub fn into_parts(self) -> (Error, W) { + (self.1, self.0) + } } #[stable(feature = "rust1", since = "1.0.0")] From b777552167d2651ceb13437f9fde4dca95045912 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 4 Dec 2020 17:32:26 +0000 Subject: [PATCH 3/3] IntoInnerError: Provide into_error Signed-off-by: Ian Jackson --- library/std/src/io/buffered/mod.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/library/std/src/io/buffered/mod.rs b/library/std/src/io/buffered/mod.rs index 0b58e55ed1731..65497817f8160 100644 --- a/library/std/src/io/buffered/mod.rs +++ b/library/std/src/io/buffered/mod.rs @@ -127,6 +127,27 @@ impl IntoInnerError { self.0 } + /// Consumes the [`IntoInnerError`] and returns the error which caused the call to + /// [`BufWriter::into_inner()`] to fail. Unlike `error`, this can be used to + /// obtain ownership of the underlying error. + /// + /// # Example + /// ``` + /// #![feature(io_into_inner_error_parts)] + /// use std::io::{BufWriter, ErrorKind, Write}; + /// + /// let mut not_enough_space = [0u8; 10]; + /// let mut stream = BufWriter::new(not_enough_space.as_mut()); + /// write!(stream, "this cannot be actually written").unwrap(); + /// let into_inner_err = stream.into_inner().expect_err("now we discover it's too small"); + /// let err = into_inner_err.into_error(); + /// assert_eq!(err.kind(), ErrorKind::WriteZero); + /// ``` + #[unstable(feature = "io_into_inner_error_parts", issue = "79704")] + pub fn into_error(self) -> Error { + self.1 + } + /// Consumes the [`IntoInnerError`] and returns the error which caused the call to /// [`BufWriter::into_inner()`] to fail, and the underlying writer. ///