1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 use marker
::{Send, Sync}
;
16 use option
::Option
::{self, Some, None}
;
20 /// A type for results generated by I/O related functions where the `Err` type
21 /// is hard-wired to `io::Error`.
23 /// This typedef is generally used to avoid writing out `io::Error` directly and
24 /// is otherwise a direct mapping to `std::result::Result`.
25 #[stable(feature = "rust1", since = "1.0.0")]
26 pub type Result
<T
> = result
::Result
<T
, Error
>;
28 /// The error type for I/O operations of the `Read`, `Write`, `Seek`, and
29 /// associated traits.
31 /// Errors mostly originate from the underlying OS, but custom instances of
32 /// `Error` can be created with crafted error messages and a particular value of
35 #[stable(feature = "rust1", since = "1.0.0")]
48 error
: Box
<error
::Error
+Send
+Sync
>,
51 /// A list specifying general categories of I/O error.
53 /// This list is intended to grow over time and it is not recommended to
54 /// exhaustively match against it.
55 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
56 #[stable(feature = "rust1", since = "1.0.0")]
58 /// An entity was not found, often a file.
59 #[stable(feature = "rust1", since = "1.0.0")]
61 /// The operation lacked the necessary privileges to complete.
62 #[stable(feature = "rust1", since = "1.0.0")]
64 /// The connection was refused by the remote server.
65 #[stable(feature = "rust1", since = "1.0.0")]
67 /// The connection was reset by the remote server.
68 #[stable(feature = "rust1", since = "1.0.0")]
70 /// The connection was aborted (terminated) by the remote server.
71 #[stable(feature = "rust1", since = "1.0.0")]
73 /// The network operation failed because it was not connected yet.
74 #[stable(feature = "rust1", since = "1.0.0")]
76 /// A socket address could not be bound because the address is already in
78 #[stable(feature = "rust1", since = "1.0.0")]
80 /// A nonexistent interface was requested or the requested address was not
82 #[stable(feature = "rust1", since = "1.0.0")]
84 /// The operation failed because a pipe was closed.
85 #[stable(feature = "rust1", since = "1.0.0")]
87 /// An entity already exists, often a file.
88 #[stable(feature = "rust1", since = "1.0.0")]
90 /// The operation needs to block to complete, but the blocking operation was
91 /// requested to not occur.
92 #[stable(feature = "rust1", since = "1.0.0")]
94 /// A parameter was incorrect.
95 #[stable(feature = "rust1", since = "1.0.0")]
97 /// Data not valid for the operation were encountered.
99 /// Unlike `InvalidInput`, this typically means that the operation
100 /// parameters were valid, however the error was caused by malformed
102 #[stable(feature = "io_invalid_data", since = "1.2.0")]
104 /// The I/O operation's timeout expired, causing it to be canceled.
105 #[stable(feature = "rust1", since = "1.0.0")]
107 /// An error returned when an operation could not be completed because a
108 /// call to `write` returned `Ok(0)`.
110 /// This typically means that an operation could only succeed if it wrote a
111 /// particular number of bytes but only a smaller number of bytes could be
113 #[stable(feature = "rust1", since = "1.0.0")]
115 /// This operation was interrupted.
117 /// Interrupted operations can typically be retried.
118 #[stable(feature = "rust1", since = "1.0.0")]
120 /// Any I/O error not part of this list.
121 #[stable(feature = "rust1", since = "1.0.0")]
124 /// Any I/O error not part of this list.
125 #[unstable(feature = "io_error_internals",
126 reason
= "better expressed through extensible enums that this \
127 enum cannot be exhaustively matched against")]
133 /// Creates a new I/O error from a known kind of error as well as an
134 /// arbitrary error payload.
136 /// This function is used to generically create I/O errors which do not
137 /// originate from the OS itself. The `error` argument is an arbitrary
138 /// payload which will be contained in this `Error`.
143 /// use std::io::{Error, ErrorKind};
145 /// // errors can be created from strings
146 /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
148 /// // errors can also be created from other errors
149 /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
151 #[stable(feature = "rust1", since = "1.0.0")]
152 pub fn new
<E
>(kind
: ErrorKind
, error
: E
) -> Error
153 where E
: Into
<Box
<error
::Error
+Send
+Sync
>>
156 repr
: Repr
::Custom(Box
::new(Custom
{
163 /// Returns an error representing the last OS error which occurred.
165 /// This function reads the value of `errno` for the target platform (e.g.
166 /// `GetLastError` on Windows) and will return a corresponding instance of
167 /// `Error` for the error code.
168 #[stable(feature = "rust1", since = "1.0.0")]
169 pub fn last_os_error() -> Error
{
170 Error
::from_raw_os_error(sys
::os
::errno() as i32)
173 /// Creates a new instance of an `Error` from a particular OS error code.
174 #[stable(feature = "rust1", since = "1.0.0")]
175 pub fn from_raw_os_error(code
: i32) -> Error
{
176 Error { repr: Repr::Os(code) }
179 /// Returns the OS error that this error represents (if any).
181 /// If this `Error` was constructed via `last_os_error` or
182 /// `from_raw_os_error`, then this function will return `Some`, otherwise
183 /// it will return `None`.
184 #[stable(feature = "rust1", since = "1.0.0")]
185 pub fn raw_os_error(&self) -> Option
<i32> {
187 Repr
::Os(i
) => Some(i
),
188 Repr
::Custom(..) => None
,
192 /// Returns a reference to the inner error wrapped by this error (if any).
194 /// If this `Error` was constructed via `new` then this function will
195 /// return `Some`, otherwise it will return `None`.
196 #[unstable(feature = "io_error_inner",
197 reason
= "recently added and requires UFCS to downcast")]
198 pub fn get_ref(&self) -> Option
<&(error
::Error
+Send
+Sync
+'
static)> {
200 Repr
::Os(..) => None
,
201 Repr
::Custom(ref c
) => Some(&*c
.error
),
205 /// Returns a mutable reference to the inner error wrapped by this error
208 /// If this `Error` was constructed via `new` then this function will
209 /// return `Some`, otherwise it will return `None`.
210 #[unstable(feature = "io_error_inner",
211 reason
= "recently added and requires UFCS to downcast")]
212 pub fn get_mut(&mut self) -> Option
<&mut (error
::Error
+Send
+Sync
+'
static)> {
214 Repr
::Os(..) => None
,
215 Repr
::Custom(ref mut c
) => Some(&mut *c
.error
),
219 /// Consumes the `Error`, returning its inner error (if any).
221 /// If this `Error` was constructed via `new` then this function will
222 /// return `Some`, otherwise it will return `None`.
223 #[unstable(feature = "io_error_inner",
224 reason
= "recently added and requires UFCS to downcast")]
225 pub fn into_inner(self) -> Option
<Box
<error
::Error
+Send
+Sync
>> {
227 Repr
::Os(..) => None
,
228 Repr
::Custom(c
) => Some(c
.error
)
232 /// Returns the corresponding `ErrorKind` for this error.
233 #[stable(feature = "rust1", since = "1.0.0")]
234 pub fn kind(&self) -> ErrorKind
{
236 Repr
::Os(code
) => sys
::decode_error_kind(code
),
237 Repr
::Custom(ref c
) => c
.kind
,
242 impl fmt
::Debug
for Repr
{
243 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
245 &Repr
::Os(ref code
) =>
246 fmt
.debug_struct("Os").field("code", code
)
247 .field("message", &sys
::os
::error_string(*code
)).finish(),
248 &Repr
::Custom(ref c
) => fmt
.debug_tuple("Custom").field(c
).finish(),
253 #[stable(feature = "rust1", since = "1.0.0")]
254 impl fmt
::Display
for Error
{
255 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
258 let detail
= sys
::os
::error_string(code
);
259 write
!(fmt
, "{} (os error {})", detail
, code
)
261 Repr
::Custom(ref c
) => c
.error
.fmt(fmt
),
266 #[stable(feature = "rust1", since = "1.0.0")]
267 impl error
::Error
for Error
{
268 fn description(&self) -> &str {
270 Repr
::Os(..) => "os error",
271 Repr
::Custom(ref c
) => c
.error
.description(),
275 fn cause(&self) -> Option
<&error
::Error
> {
277 Repr
::Os(..) => None
,
278 Repr
::Custom(ref c
) => c
.error
.cause(),
283 fn _assert_error_is_sync_send() {
284 fn _is_sync_send
<T
: Sync
+Send
>() {}
285 _is_sync_send
::<Error
>();
291 use super::{Error, ErrorKind}
;
293 use error
::Error
as error_Error
;
295 use sys
::os
::error_string
;
298 fn test_debug_error() {
300 let msg
= error_string(code
);
301 let err
= Error { repr: super::Repr::Os(code) }
;
302 let expected
= format
!("Error {{ repr: Os {{ code: {:?}, message: {:?} }} }}", code
, msg
);
303 assert_eq
!(format
!("{:?}", err
), expected
);
307 fn test_downcasting() {
311 impl fmt
::Display
for TestError
{
312 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
317 impl error
::Error
for TestError
{
318 fn description(&self) -> &str {
323 // we have to call all of these UFCS style right now since method
324 // resolution won't implicitly drop the Send+Sync bounds
325 let mut err
= Error
::new(ErrorKind
::Other
, TestError
);
326 assert
!(error
::Error
::is
::<TestError
>(err
.get_ref().unwrap()));
327 assert_eq
!("asdf", err
.get_ref().unwrap().description());
328 assert
!(error
::Error
::is
::<TestError
>(err
.get_mut().unwrap()));
329 let extracted
= err
.into_inner().unwrap();
330 error
::Error
::downcast
::<TestError
>(extracted
).unwrap();