diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 717d2868abf98..6a5d015723d6c 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -278,6 +278,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 = "input", issue = "none")] +pub use self::stdio::input; #[stable(feature = "rust1", since = "1.0.0")] pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index d6b7ad6254a8c..3a3127dba5594 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -5,7 +5,9 @@ use crate::io::prelude::*; use crate::cell::RefCell; use crate::fmt; use crate::io::lazy::Lazy; -use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter}; +use crate::io::{ + self, BufReader, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, LineWriter, Result, Write, +}; use crate::sync::{Arc, Mutex, MutexGuard, Once}; use crate::sys::stdio; use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; @@ -872,6 +874,44 @@ impl fmt::Debug for StderrLock<'_> { } } +/// Prints the given `str` and 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(input)] +/// use std::io; +/// +/// fn main() { +/// let name = io::input("Enter name: ").expect("input failed!"); +/// +/// println!("Your name is {}!", name); +/// } +/// ``` +#[unstable( + feature = "input", + reason = "this function may be replaced with a more general mechanism", + issue = "none" +)] +pub fn input(prompt: &str) -> Result { + let stdout = stdout(); + let mut lock = stdout.lock(); + lock.write_all(prompt.as_bytes())?; + lock.flush()?; + let mut input = String::new(); + match stdin().read_line(&mut input)? { + 0 => Err(Error::new(ErrorKind::UnexpectedEof, "input reached eof unexpectedly")), + _ => Ok(String::from(input.trim_end_matches(&['\n', '\r'][..]))), + } +} + /// Resets the thread-local stderr handle to the specified writer /// /// This will replace the current thread's stderr handle, returning the old diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bd585d39c242f..83db285e142bd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -274,6 +274,7 @@ #![feature(global_asm)] #![feature(hash_raw_entry)] #![feature(hashmap_internals)] +#![feature(input)] #![feature(int_error_internals)] #![feature(int_error_matching)] #![feature(into_future)]