Skip to content

Add more std::io documentation. #26903

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

Merged
merged 1 commit into from
Jul 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
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
32 changes: 29 additions & 3 deletions src/libstd/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,37 @@ use option::Option::{self, Some, None};
use result;
use sys;

/// A type for results generated by I/O related functions where the `Err` type
/// is hard-wired to `io::Error`.
/// A specialized [`Result`][result] type for I/O operations.
///
/// [result]: ../result/enum.Result.html
///
/// This type is broadly used across `std::io` for any operation which may
/// produce an error.
///
/// This typedef is generally used to avoid writing out `io::Error` directly and
/// is otherwise a direct mapping to `std::result::Result`.
/// is otherwise a direct mapping to `Result`.
///
/// While usual Rust style is to import types directly, aliases of `Result`
/// often are not, to make it easier to distinguish between them. `Result` is
/// generally assumed to be `std::result::Result`, and so users of this alias
/// will generally use `io::Result` instead of shadowing the prelude's import
/// of `std::result::Result`.
///
/// # Examples
///
/// A convenience function that bubbles an `io::Result` to its caller:
///
/// ```
/// use std::io;
///
/// fn get_string() -> io::Result<String> {
/// let mut buffer = String::new();
///
/// try!(io::stdin().read_line(&mut buffer));
///
/// Ok(buffer)
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub type Result<T> = result::Result<T, Error>;

Expand Down
112 changes: 97 additions & 15 deletions src/libstd/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,42 @@ pub struct StdinLock<'a> {
inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>,
}

/// Creates a new handle to the global standard input stream of this process.
/// Constructs a new handle to the standard input of the current process.
///
/// The handle returned refers to a globally shared buffer between all threads.
/// Access is synchronized and can be explicitly controlled with the `lock()`
/// method.
/// Each handle returned is a reference to a shared global buffer whose access
/// is synchronized via a mutex. If you need more explicit control over
/// locking, see the [lock() method][lock].
///
/// [lock]: struct.Stdin.html#method.lock
///
/// # Examples
///
/// Using implicit synchronization:
///
/// ```
/// use std::io::{self, Read};
///
/// # fn foo() -> io::Result<String> {
/// let mut buffer = String::new();
/// try!(io::stdin().read_to_string(&mut buffer));
/// # Ok(buffer)
/// # }
/// ```
///
/// Using explicit synchronization:
///
/// The `Read` trait is implemented for the returned value but the `BufRead`
/// trait is not due to the global nature of the standard input stream. The
/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
/// ```
/// use std::io::{self, Read};
///
/// # fn foo() -> io::Result<String> {
/// let mut buffer = String::new();
/// let stdin = io::stdin();
/// let mut handle = stdin.lock();
///
/// try!(handle.read_to_string(&mut buffer));
/// # Ok(buffer)
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdin() -> Stdin {
static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = Lazy::new(stdin_init);
Expand Down Expand Up @@ -298,13 +325,42 @@ pub struct StdoutLock<'a> {
inner: ReentrantMutexGuard<'a, RefCell<LineWriter<Maybe<StdoutRaw>>>>,
}

/// Constructs a new reference to the standard output of the current process.
/// Constructs a new handle to the standard output of the current process.
///
/// Each handle returned is a reference to a shared global buffer whose access
/// is synchronized via a mutex. Explicit control over synchronization is
/// provided via the `lock` method.
/// is synchronized via a mutex. If you need more explicit control over
/// locking, see the [lock() method][lock].
///
/// [lock]: struct.Stdout.html#method.lock
///
/// # Examples
///
/// Using implicit synchronization:
///
/// ```
/// use std::io::{self, Write};
///
/// # fn foo() -> io::Result<()> {
/// try!(io::stdout().write(b"hello world"));
///
/// The returned handle implements the `Write` trait.
/// # Ok(())
/// # }
/// ```
///
/// Using explicit synchronization:
///
/// ```
/// use std::io::{self, Write};
///
/// # fn foo() -> io::Result<()> {
/// let stdout = io::stdout();
/// let mut handle = stdout.lock();
///
/// try!(handle.write(b"hello world"));
///
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdout() -> Stdout {
static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>
Expand Down Expand Up @@ -376,12 +432,38 @@ pub struct StderrLock<'a> {
inner: ReentrantMutexGuard<'a, RefCell<Maybe<StderrRaw>>>,
}

/// Constructs a new reference to the standard error stream of a process.
/// Constructs a new handle to the standard error of the current process.
///
/// This handle is not buffered.
///
/// # Examples
///
/// Using implicit synchronization:
///
/// ```
/// use std::io::{self, Write};
///
/// # fn foo() -> io::Result<()> {
/// try!(io::stderr().write(b"hello world"));
///
/// # Ok(())
/// # }
/// ```
///
/// Using explicit synchronization:
///
/// ```
/// use std::io::{self, Write};
///
/// # fn foo() -> io::Result<()> {
/// let stderr = io::stderr();
/// let mut handle = stderr.lock();
///
/// Each returned handle is synchronized amongst all other handles created from
/// this function. No handles are buffered, however.
/// try!(handle.write(b"hello world"));
///
/// The returned handle implements the `Write` trait.
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stderr() -> Stderr {
static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> = Lazy::new(stderr_init);
Expand Down
33 changes: 32 additions & 1 deletion src/libstd/io/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ use io::{self, Read, Write, ErrorKind, BufRead};
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
///
/// # Examples
///
/// ```
/// use std::io;
///
/// # fn foo() -> io::Result<()> {
/// let mut reader: &[u8] = b"hello";
/// let mut writer: Vec<u8> = vec![];
///
/// try!(io::copy(&mut reader, &mut writer));
///
/// assert_eq!(reader, &writer[..]);
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
let mut buf = [0; super::DEFAULT_BUF_SIZE];
Expand All @@ -48,9 +64,24 @@ pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Creates an instance of an empty reader.
/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// use std::io;
/// use std::io::Read;
///
/// # fn foo() -> io::Result<String> {
/// let mut buffer = String::new();
/// try!(io::empty().read_to_string(&mut buffer));
/// # Ok(buffer)
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

Expand Down