Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions text/0841-read_to_string_without_buffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
- Feature Name: read_to_string_without_buffer
- Start Date: 2015-03-13
- RFC PR: https://github.com/rust-lang/rfcs/pull/970
- Rust Issue:

# Summary

Add back `read_to_string` and `read_to_end` methods to the `Read` trait that
don't take a buffer.

# Motivation

While the `fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<()>` and
`fn read_to_string(&mut self, buf: &mut String) -> Result<()>` APIs are more
efficient removing the APIs that don't require passing a buffer entirely comes
at with convenience loss in some situations. In particular if one want's to
implement a chaining API and doesn't care about efficiency.

Today we either have to write this

```rust
fn get_last_commit () -> String {

let output = Command::new("git")
.arg("rev-parse")
.arg("HEAD")
.output()
.ok().expect("error invoking git rev-parse");

let encoded = String::from_utf8(output.stdout).ok().expect("error parsing output of git rev-parse");

encoded
}
```

Or this:


```rust
fn get_last_commit () -> String {

Command::new("git")
.arg("rev-parse")
.arg("HEAD")
.output()
.map(|output| {
String::from_utf8(output.stdout).ok().expect("error reading into string")
})
.ok().expect("error invoking git rev-parse")
}
```

But we'd like to be able to just write

```rust
fn get_last_commit () -> String {

Command::new("git")
.arg("rev-parse")
.arg("HEAD")
.spawn()
.ok().expect("error spawning process")
.stdout.read_to_string()
.ok().expect("error reading output")
}
```

This was possible before but since there is not such `read_to_string` API
anymore, it's currently impossible.


# Detailed design

Add back methods with following signature

`fn read_to_end(&mut self) -> Result<Vec<u8>>`

`fn read_to_string(&mut self) -> Result<String>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't these conflict with the existing read_to_end and read_to_string methods?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. What's the state of method overloading in Rust? I've been basically away from Rust for the last couple of months which means I have to start over. If there's no such thing as method overloading I'd need to give them other names.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can provide multiple methods of the same name from differing traits, and use UFCS (ie ReadExt::read_to_end(&mut rdr, Vec::new())) to differentiate. But that would not improve the convenience you mentioned in this RFC. You'd need a new name.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read_into_vec and read_into_string, possibly

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reem I like those, updated the PR


# Drawbacks

Two more methods to maintain

# Alternatives

Don't do it and force users to use things like `map` for chaining

# Unresolved questions

None.