Skip to content

Commit

Permalink
Rollup merge of rust-lang#80217 - camelid:io-read_to_string, r=m-ou-se
Browse files Browse the repository at this point in the history
Add a `std::io::read_to_string` function

I recognize that you're usually supposed to open an issue first, but the
implementation is very small so it's okay if this is closed and it was 'wasted
work' :)

-----

The equivalent of `std::fs::read_to_string`, but generalized to all
`Read` impls.

As the documentation on `std::io::read_to_string` says, the advantage of
this function is that it means you don't have to create a variable first
and it provides more type safety since you can only get the buffer out
if there were no errors. If you use `Read::read_to_string`, you have to
remember to check whether the read succeeded because otherwise your
buffer will be empty.

It's friendlier to newcomers and better in most cases to use an explicit
return value instead of an out parameter.
  • Loading branch information
JohnTitor authored Jan 14, 2021
2 parents dba82da + 7463292 commit 97466c6
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,54 @@ pub trait Read {
}
}

/// Read all bytes from a [reader][Read] into a new [`String`].
///
/// This is a convenience function for [`Read::read_to_string`]. Using this
/// function avoids having to create a variable first and provides more type
/// safety since you can only get the buffer out if there were no errors. (If you
/// use [`Read::read_to_string`] you have to remember to check whether the read
/// succeeded because otherwise your buffer will be empty or only partially full.)
///
/// # Performance
///
/// The downside of this function's increased ease of use and type safety is
/// that it gives you less control over performance. For example, you can't
/// pre-allocate memory like you can using [`String::with_capacity`] and
/// [`Read::read_to_string`]. Also, you can't re-use the buffer if an error
/// occurs while reading.
///
/// In many cases, this function's performance will be adequate and the ease of use
/// and type safety tradeoffs will be worth it. However, there are cases where you
/// need more control over performance, and in those cases you should definitely use
/// [`Read::read_to_string`] directly.
///
/// # Errors
///
/// This function forces you to handle errors because the output (the `String`)
/// is wrapped in a [`Result`]. See [`Read::read_to_string`] for the errors
/// that can occur. If any error occurs, you will get an [`Err`], so you
/// don't have to worry about your buffer being empty or partially full.
///
/// # Examples
///
/// ```no_run
/// #![feature(io_read_to_string)]
///
/// # use std::io;
/// fn main() -> io::Result<()> {
/// let stdin = io::read_to_string(&mut io::stdin())?;
/// println!("Stdin was:");
/// println!("{}", stdin);
/// Ok(())
/// }
/// ```
#[unstable(feature = "io_read_to_string", issue = "80218")]
pub fn read_to_string<R: Read>(reader: &mut R) -> Result<String> {
let mut buf = String::new();
reader.read_to_string(&mut buf)?;
Ok(buf)
}

/// A buffer type used with `Read::read_vectored`.
///
/// It is semantically a wrapper around an `&mut [u8]`, but is guaranteed to be
Expand Down

0 comments on commit 97466c6

Please sign in to comment.