about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorMark-Simulacrum <mark.simulacrum@gmail.com>2016-11-01 19:19:33 -0600
committerMark-Simulacrum <mark.simulacrum@gmail.com>2016-11-02 09:01:14 -0600
commit99234bbe9e9f89dcfdf28b9ee53fbcece5f19abb (patch)
treeefb047771cdd2f47053c9d026f7f88bbe69423d9 /src/libstd
parentea4b94dab0d526135dd658d3a314cc5462d439b0 (diff)
downloadrust-99234bbe9e9f89dcfdf28b9ee53fbcece5f19abb.tar.gz
rust-99234bbe9e9f89dcfdf28b9ee53fbcece5f19abb.zip
Add a new non-heap allocated variant to io::Error's representation.
Implement From<ErrorKind> for io::Error, intended for use with errors
that should never be exposed to the user.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/error.rs69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index ddf0030858e..659c8aa5aea 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>),
 }
 
@@ -171,6 +173,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 +324,7 @@ impl Error {
         match self.repr {
             Repr::Os(i) => Some(i),
             Repr::Custom(..) => None,
+            Repr::Simple(..) => None,
         }
     }
 
@@ -317,6 +357,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 +428,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 +462,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 +490,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 +502,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 +516,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 +525,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 +533,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(),
         }
     }