about summary refs log tree commit diff
path: root/src/libstd/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/io')
-rw-r--r--src/libstd/io/error.rs78
-rw-r--r--src/libstd/io/mod.rs27
-rw-r--r--src/libstd/io/stdio.rs3
3 files changed, 74 insertions, 34 deletions
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index ddf0030858e..795c89c0007 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -12,6 +12,7 @@ use error;
 use fmt;
 use result;
 use sys;
+use convert::From;
 
 /// A specialized [`Result`](../result/enum.Result.html) type for I/O
 /// operations.
@@ -62,6 +63,7 @@ pub struct Error {
 
 enum Repr {
     Os(i32),
+    Simple(ErrorKind),
     Custom(Box<Custom>),
 }
 
@@ -124,23 +126,28 @@ pub enum ErrorKind {
     InvalidInput,
     /// Data not valid for the operation were encountered.
     ///
-    /// Unlike `InvalidInput`, this typically means that the operation
+    /// Unlike [`InvalidInput`], this typically means that the operation
     /// parameters were valid, however the error was caused by malformed
     /// input data.
     ///
     /// For example, a function that reads a file into a string will error with
     /// `InvalidData` if the file's contents are not valid UTF-8.
+    ///
+    /// [`InvalidInput`]: #variant.InvalidInput
     #[stable(feature = "io_invalid_data", since = "1.2.0")]
     InvalidData,
     /// The I/O operation's timeout expired, causing it to be canceled.
     #[stable(feature = "rust1", since = "1.0.0")]
     TimedOut,
     /// An error returned when an operation could not be completed because a
-    /// call to `write` returned `Ok(0)`.
+    /// call to [`write()`] returned [`Ok(0)`].
     ///
     /// This typically means that an operation could only succeed if it wrote a
     /// particular number of bytes but only a smaller number of bytes could be
     /// written.
+    ///
+    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`Ok(0)`]: ../../std/io/type.Result.html
     #[stable(feature = "rust1", since = "1.0.0")]
     WriteZero,
     /// This operation was interrupted.
@@ -171,6 +178,43 @@ pub enum ErrorKind {
     __Nonexhaustive,
 }
 
+impl ErrorKind {
+    fn as_str(&self) -> &'static str {
+        match *self {
+            ErrorKind::NotFound => "entity not found",
+            ErrorKind::PermissionDenied => "permission denied",
+            ErrorKind::ConnectionRefused => "connection refused",
+            ErrorKind::ConnectionReset => "connection reset",
+            ErrorKind::ConnectionAborted => "connection aborted",
+            ErrorKind::NotConnected => "not connected",
+            ErrorKind::AddrInUse => "address in use",
+            ErrorKind::AddrNotAvailable => "address not available",
+            ErrorKind::BrokenPipe => "broken pipe",
+            ErrorKind::AlreadyExists => "entity already exists",
+            ErrorKind::WouldBlock => "operation would block",
+            ErrorKind::InvalidInput => "invalid input parameter",
+            ErrorKind::InvalidData => "invalid data",
+            ErrorKind::TimedOut => "timed out",
+            ErrorKind::WriteZero => "write zero",
+            ErrorKind::Interrupted => "operation interrupted",
+            ErrorKind::Other => "other os error",
+            ErrorKind::UnexpectedEof => "unexpected end of file",
+            ErrorKind::__Nonexhaustive => unreachable!()
+        }
+    }
+}
+
+/// Intended for use for errors not exposed to the user, where allocating onto
+/// the heap (for normal construction via Error::new) is too costly.
+#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
+impl From<ErrorKind> for Error {
+    fn from(kind: ErrorKind) -> Error {
+        Error {
+            repr: Repr::Simple(kind)
+        }
+    }
+}
+
 impl Error {
     /// Creates a new I/O error from a known kind of error as well as an
     /// arbitrary error payload.
@@ -285,6 +329,7 @@ impl Error {
         match self.repr {
             Repr::Os(i) => Some(i),
             Repr::Custom(..) => None,
+            Repr::Simple(..) => None,
         }
     }
 
@@ -317,6 +362,7 @@ impl Error {
     pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
         match self.repr {
             Repr::Os(..) => None,
+            Repr::Simple(..) => None,
             Repr::Custom(ref c) => Some(&*c.error),
         }
     }
@@ -387,6 +433,7 @@ impl Error {
     pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
         match self.repr {
             Repr::Os(..) => None,
+            Repr::Simple(..) => None,
             Repr::Custom(ref mut c) => Some(&mut *c.error),
         }
     }
@@ -420,6 +467,7 @@ impl Error {
     pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
         match self.repr {
             Repr::Os(..) => None,
+            Repr::Simple(..) => None,
             Repr::Custom(c) => Some(c.error)
         }
     }
@@ -447,6 +495,7 @@ impl Error {
         match self.repr {
             Repr::Os(code) => sys::decode_error_kind(code),
             Repr::Custom(ref c) => c.kind,
+            Repr::Simple(kind) => kind,
         }
     }
 }
@@ -458,6 +507,7 @@ impl fmt::Debug for Repr {
                 fmt.debug_struct("Os").field("code", code)
                    .field("message", &sys::os::error_string(*code)).finish(),
             Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
+            Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
         }
     }
 }
@@ -471,6 +521,7 @@ impl fmt::Display for Error {
                 write!(fmt, "{} (os error {})", detail, code)
             }
             Repr::Custom(ref c) => c.error.fmt(fmt),
+            Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
         }
     }
 }
@@ -479,27 +530,7 @@ impl fmt::Display for Error {
 impl error::Error for Error {
     fn description(&self) -> &str {
         match self.repr {
-            Repr::Os(..) => match self.kind() {
-                ErrorKind::NotFound => "entity not found",
-                ErrorKind::PermissionDenied => "permission denied",
-                ErrorKind::ConnectionRefused => "connection refused",
-                ErrorKind::ConnectionReset => "connection reset",
-                ErrorKind::ConnectionAborted => "connection aborted",
-                ErrorKind::NotConnected => "not connected",
-                ErrorKind::AddrInUse => "address in use",
-                ErrorKind::AddrNotAvailable => "address not available",
-                ErrorKind::BrokenPipe => "broken pipe",
-                ErrorKind::AlreadyExists => "entity already exists",
-                ErrorKind::WouldBlock => "operation would block",
-                ErrorKind::InvalidInput => "invalid input parameter",
-                ErrorKind::InvalidData => "invalid data",
-                ErrorKind::TimedOut => "timed out",
-                ErrorKind::WriteZero => "write zero",
-                ErrorKind::Interrupted => "operation interrupted",
-                ErrorKind::Other => "other os error",
-                ErrorKind::UnexpectedEof => "unexpected end of file",
-                ErrorKind::__Nonexhaustive => unreachable!()
-            },
+            Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
             Repr::Custom(ref c) => c.error.description(),
         }
     }
@@ -507,6 +538,7 @@ impl error::Error for Error {
     fn cause(&self) -> Option<&error::Error> {
         match self.repr {
             Repr::Os(..) => None,
+            Repr::Simple(..) => None,
             Repr::Custom(ref c) => c.error.cause(),
         }
     }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 193f396c0d4..ad9ae5638b6 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -21,7 +21,7 @@
 //! of other types, and you can implement them for your types too. As such,
 //! you'll see a few different types of I/O throughout the documentation in
 //! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For
-//! example, `Read` adds a `read()` method, which we can use on `File`s:
+//! example, [`Read`] adds a [`read()`] method, which we can use on `File`s:
 //!
 //! ```
 //! use std::io;
@@ -251,6 +251,7 @@
 //! [`Lines`]: struct.Lines.html
 //! [`io::Result`]: type.Result.html
 //! [`try!`]: ../macro.try.html
+//! [`read()`]: trait.Read.html#tymethod.read
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -814,19 +815,23 @@ pub trait Read {
 ///
 /// Implementors of the `Write` trait are sometimes called 'writers'.
 ///
-/// Writers are defined by two required methods, `write()` and `flush()`:
+/// Writers are defined by two required methods, [`write()`] and [`flush()`]:
 ///
-/// * The `write()` method will attempt to write some data into the object,
+/// * The [`write()`] method will attempt to write some data into the object,
 ///   returning how many bytes were successfully written.
 ///
-/// * The `flush()` method is useful for adaptors and explicit buffers
+/// * The [`flush()`] method is useful for adaptors and explicit buffers
 ///   themselves for ensuring that all buffered data has been pushed out to the
 ///   'true sink'.
 ///
 /// Writers are intended to be composable with one another. Many implementors
-/// throughout `std::io` take and provide types which implement the `Write`
+/// throughout [`std::io`] take and provide types which implement the `Write`
 /// trait.
 ///
+/// [`write()`]: #tymethod.write
+/// [`flush()`]: #tymethod.flush
+/// [`std::io`]: index.html
+///
 /// # Examples
 ///
 /// ```
@@ -1475,10 +1480,10 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
 
 /// Reader adaptor which limits the bytes read from an underlying reader.
 ///
-/// This struct is generally created by calling [`take()`][take] on a reader.
-/// Please see the documentation of `take()` for more details.
+/// This struct is generally created by calling [`take()`] on a reader.
+/// Please see the documentation of [`take()`] for more details.
 ///
-/// [take]: trait.Read.html#method.take
+/// [`take()`]: trait.Read.html#method.take
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Take<T> {
     inner: T,
@@ -1491,8 +1496,10 @@ impl<T> Take<T> {
     ///
     /// # Note
     ///
-    /// This instance may reach EOF after reading fewer bytes than indicated by
-    /// this method if the underlying `Read` instance reaches EOF.
+    /// This instance may reach `EOF` after reading fewer bytes than indicated by
+    /// this method if the underlying [`Read`] instance reaches EOF.
+    ///
+    /// [`Read`]: ../../std/io/trait.Read.html
     ///
     /// # Examples
     ///
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 27bc5f0890c..f6ee0be47fa 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -324,10 +324,11 @@ impl<'a> BufRead for StdinLock<'a> {
 ///
 /// Each handle shares a global buffer of data to be written to the standard
 /// output stream. Access is also synchronized via a lock and explicit control
-/// over locking is available via the `lock` method.
+/// over locking is available via the [`lock()`] method.
 ///
 /// Created by the [`io::stdout`] method.
 ///
+/// [`lock()`]: #method.lock
 /// [`io::stdout`]: fn.stdout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {