// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use boxed::Box; use clone::Clone; use error; use fmt; use option::Option::{self, Some, None}; use result; use string::String; use sys; /// A type for results generated by I/O related functions where the `Err` type /// is hard-wired to `io::Error`. /// /// This typedef is generally used to avoid writing out `io::Error` directly and /// is otherwise a direct mapping to `std::result::Result`. #[stable(feature = "rust1", since = "1.0.0")] pub type Result = result::Result; /// The error type for I/O operations of the `Read`, `Write`, `Seek`, and /// associated traits. /// /// Errors mostly originate from the underlying OS, but custom instances of /// `Error` can be created with crafted error messages and a particular value of /// `ErrorKind`. #[derive(PartialEq, Eq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Error { repr: Repr, } #[derive(PartialEq, Eq, Clone, Debug)] enum Repr { Os(i32), Custom(Box), } #[derive(PartialEq, Eq, Clone, Debug)] struct Custom { kind: ErrorKind, desc: &'static str, detail: Option } /// A list specifying general categories of I/O error. #[derive(Copy, PartialEq, Eq, Clone, Debug)] #[unstable(feature = "io", reason = "the interaction between OS error codes and how they map to \ these names (as well as the names themselves) has not \ been thoroughly thought out")] pub enum ErrorKind { /// The file was not found. FileNotFound, /// The file permissions disallowed access to this file. PermissionDenied, /// The connection was refused by the remote server. ConnectionRefused, /// The connection was reset by the remote server. ConnectionReset, /// The connection was aborted (terminated) by the remote server. ConnectionAborted, /// The network operation failed because it was not connected yet. NotConnected, /// The operation failed because a pipe was closed. BrokenPipe, /// A file already existed with that name. PathAlreadyExists, /// No file exists at that location. PathDoesntExist, /// The path did not specify the type of file that this operation required. /// For example, attempting to copy a directory with the `fs::copy()` /// operation will fail with this error. MismatchedFileTypeForOperation, /// The operation temporarily failed (for example, because a signal was /// received), and retrying may succeed. ResourceUnavailable, /// A parameter was incorrect in a way that caused an I/O error not part of /// this list. InvalidInput, /// The I/O operation's timeout expired, causing it to be canceled. TimedOut, /// An error returned when an operation could not be completed because a /// 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. WriteZero, /// This operation was interrupted Interrupted, /// Any I/O error not part of this list. Other, } impl Error { /// Creates a new custom error from a specified kind/description/detail. #[unstable(feature = "io", reason = "the exact makeup of an Error may change to include `Box` for \ example")] pub fn new(kind: ErrorKind, description: &'static str, detail: Option) -> Error { Error { repr: Repr::Custom(Box::new(Custom { kind: kind, desc: description, detail: detail, })) } } /// Returns an error representing the last OS error which occurred. /// /// This function reads the value of `errno` for the target platform (e.g. /// `GetLastError` on Windows) and will return a corresponding instance of /// `Error` for the error code. #[stable(feature = "rust1", since = "1.0.0")] pub fn last_os_error() -> Error { Error::from_os_error(sys::os::errno() as i32) } /// Creates a new instance of an `Error` from a particular OS error code. #[unstable(feature = "io", reason = "unclear whether this function is necessary")] pub fn from_os_error(code: i32) -> Error { Error { repr: Repr::Os(code) } } /// Return the corresponding `ErrorKind` for this error. #[stable(feature = "rust1", since = "1.0.0")] pub fn kind(&self) -> ErrorKind { match self.repr { Repr::Os(code) => sys::decode_error_kind(code), Repr::Custom(ref c) => c.kind, } } /// Returns a short description for this error message #[unstable(feature = "io")] #[deprecated(since = "1.0.0", reason = "use the Error trait's description \ method instead")] pub fn description(&self) -> &str { match self.repr { Repr::Os(..) => "os error", Repr::Custom(ref c) => c.desc, } } /// Returns a detailed error message for this error (if one is available) #[unstable(feature = "io")] #[deprecated(since = "1.0.0", reason = "use the to_string() method instead")] pub fn detail(&self) -> Option { match self.repr { Repr::Os(code) => Some(sys::os::error_string(code)), Repr::Custom(ref s) => s.detail.clone(), } } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match self.repr { Repr::Os(code) => { let detail = sys::os::error_string(code); write!(fmt, "{} (os error {})", detail, code) } Repr::Custom(ref c) => { match **c { Custom { kind: ErrorKind::Other, desc: "unknown error", detail: Some(ref detail) } => { write!(fmt, "{}", detail) } Custom { detail: None, desc, .. } => write!(fmt, "{}", desc), Custom { detail: Some(ref detail), desc, .. } => write!(fmt, "{} ({})", desc, detail) } } } } } #[stable(feature = "rust1", since = "1.0.0")] impl error::Error for Error { fn description(&self) -> &str { match self.repr { Repr::Os(..) => "os error", Repr::Custom(ref c) => c.desc, } } }