Skip to content

Add std::io::input simple input function. #75435

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
02268cc
Update lib.rs
sHaDoW-54 Aug 12, 2020
6fac729
Update mod.rs
sHaDoW-54 Aug 12, 2020
843c2bf
Update stdio.rs
sHaDoW-54 Aug 12, 2020
6c42a62
Update stdio.rs
sHaDoW-54 Aug 12, 2020
0fc63d9
Update library/std/src/io/stdio.rs
sHaDoW-54 Aug 13, 2020
25dcd97
Update stdio.rs
sHaDoW-54 Aug 13, 2020
ebb35f1
Update mod.rs
sHaDoW-54 Aug 13, 2020
c601238
Update lib.rs
sHaDoW-54 Aug 13, 2020
ac0a700
Update stdio.rs
sHaDoW-54 Aug 13, 2020
905716b
Update stdio.rs
sHaDoW-54 Sep 13, 2020
561f85f
Update mod.rs
sHaDoW-54 Sep 13, 2020
e69e325
Update stdio.rs
sHaDoW-54 Sep 13, 2020
03d3b6f
Update stdio.rs
sHaDoW-54 Sep 13, 2020
80c2964
Update mod.rs
sHaDoW-54 Sep 13, 2020
d58892d
Update stdio.rs
sHaDoW-54 Sep 13, 2020
fd4cc45
Update stdio.rs
sHaDoW-54 Sep 13, 2020
8f2ca07
Update stdio.rs
sHaDoW-54 Sep 13, 2020
ab4fb3e
Update stdio.rs
sHaDoW-54 Sep 13, 2020
63feaa7
Update stdio.rs
sHaDoW-54 Sep 13, 2020
09d7391
Update stdio.rs
sHaDoW-54 Sep 20, 2020
e65a3a9
Update mod.rs
sHaDoW-54 Sep 20, 2020
f0571fa
Update stdio.rs
sHaDoW-54 Sep 20, 2020
2026394
Update stdio.rs
sHaDoW-54 Sep 20, 2020
e79e87b
Update stdio.rs
sHaDoW-54 Sep 20, 2020
a45bf3a
Update stdio.rs
sHaDoW-54 Sep 20, 2020
a9070fa
Update stdio.rs
sHaDoW-54 Sep 20, 2020
7710011
Update stdio.rs
sHaDoW-54 Sep 20, 2020
9d7f51f
Update stdio.rs
sHaDoW-54 Sep 21, 2020
48f9aba
Update stdio.rs
sHaDoW-54 Sep 21, 2020
4d4238e
Update stdio.rs
sHaDoW-54 Sep 21, 2020
7ae7275
Update stdio.rs
sHaDoW-54 Sep 27, 2020
790b1d1
Update stdio.rs
sHaDoW-54 Sep 27, 2020
c49a1ca
Update stdio.rs
sHaDoW-54 Sep 27, 2020
4608e07
Update stdio.rs
sHaDoW-54 Sep 27, 2020
9b681e3
Merge branch 'master' into master
sHaDoW-54 Sep 27, 2020
c571550
Update stdio.rs
sHaDoW-54 Sep 28, 2020
9aa7bf8
Update stdio.rs
sHaDoW-54 Sep 28, 2020
d9d8b01
Update stdio.rs
sHaDoW-54 Sep 28, 2020
45b8a1d
Update stdio.rs
sHaDoW-54 Sep 28, 2020
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
2 changes: 2 additions & 0 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ pub use self::buffered::{BufReader, BufWriter, LineWriter};
pub use self::cursor::Cursor;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::error::{Error, ErrorKind, Result};
#[unstable(feature = "io_input", issue = "none")]
pub use self::stdio::read_line;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
47 changes: 46 additions & 1 deletion library/std/src/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use crate::io::prelude::*;

use crate::cell::RefCell;
use crate::fmt;
use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
use crate::io::{
self, BufReader, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, LineWriter, Result, Write,
};
use crate::lazy::SyncOnceCell;
use crate::sync::{Mutex, MutexGuard};
use crate::sys::stdio;
Expand Down Expand Up @@ -873,6 +875,49 @@ impl fmt::Debug for StderrLock<'_> {
}
}

/// Reads a [`String`] from [standard input](Stdin). The trailing
/// newline is stripped. Gives an error on EOF (end of file).
///
/// # Note
///
/// If you require more explicit control over capturing
/// user input, see the [`Stdin::read_line`] method.
///
/// # Examples
///
/// ```no_run
/// #![feature(io_input)]
/// use std::io;
///
/// fn main() -> io::Result<()> {
/// print!("Enter name: ");
///
/// let name: String = io::read_line()?;
///
/// println!("Your name is {}!", name);
///
/// Ok(())
/// }
/// ```
#[unstable(
feature = "io_input",
reason = "this function may be replaced with a more general mechanism",
issue = "none"
)]
pub fn read_line() -> Result<String> {
stdout().flush()?; // print!() does not flush :(
let mut input = String::new();
match stdin().read_line(&mut input)? {
0 => Err(Error::new(ErrorKind::UnexpectedEof, "input reached eof unexpectedly")),
_ => {
input.pop();
Copy link
Member

Choose a reason for hiding this comment

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

Considering stdin().read_line() does not drop newlines, shouldn't this function keep those in tact as well? Might be a bit confusing that stdin().read_line() gives a line including the newline, and io::read_line() gives one without the newline.

I agree it's probably more useful if it already strips the newline. But I'm worried about the inconsistency between two functions with the same name.

Copy link
Author

Choose a reason for hiding this comment

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

I agree the inconsistency between stdin().read_line() and io::read_line() is concerning, but I think wanting to keep the newline would be in the minority and could be corrected with this snippet of code, perhaps we can avoid confusion by changing the name of the function?

if cfg!(windows) {
    string.push_str("\r\n");
} else if cfg!(unix) {
    string.push('\n');
}

Copy link
Member

@m-ou-se m-ou-se Sep 28, 2020

Choose a reason for hiding this comment

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

could be corrected with this snippet of code

No, that unconditionally adds a \r\n or \n. The original line might or might not end in a newline (e.g. at the end of the stream/file), and might be just a \n on Windows in certain circumstances. This is why the already existing read_line function keeps the newlines, to not throw away any information.

Anyway, I agree that a function that gives a line with the newline stripped is useful. But considering the existing read_line keeps the newlines, this shouldn't have different behaviour while using the same name. (Also, the existing read_line returns Ok for zero bytes of input, while this function returns an Err in that case.)

Is there an RFC for this? It's a bit hard right now to keep track of all the design decisions like the name, newline stripping, the possibility of parsing things, showing a prompt or not, etc. Combined with the previous PR, this has now had 108 commits/versions. Maybe it's better to first agree on the interface/api before implementing it.

Copy link
Author

Choose a reason for hiding this comment

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

That seems like a good plan, i believe it was mentioned in the previous PR that there have been RFC's on this before.

Copy link
Contributor

Choose a reason for hiding this comment

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

A better choice may be to change the naming to reflect that it does not include the new lines, at least that could solve the problem with naming inconsistency.

But if we keep the line, then people would need to fallback to trim which currently does not return a String in place but &str.

#[cfg(windows)]
input.pop();
Ok(input)
}
}
}

/// Resets the thread-local stderr handle to the specified writer
///
/// This will replace the current thread's stderr handle, returning the old
Expand Down