1 #[cfg(test)]
2 mod tests;
3
4 use crate::convert::From;
5 use crate::error;
6 use crate::fmt;
7 use crate::result;
8 use crate::sys;
9
10 /// A specialized [`Result`] type for I/O operations.
11 ///
12 /// This type is broadly used across [`std::io`] for any operation which may
13 /// produce an error.
14 ///
15 /// This typedef is generally used to avoid writing out [`io::Error`] directly and
16 /// is otherwise a direct mapping to [`Result`].
17 ///
18 /// While usual Rust style is to import types directly, aliases of [`Result`]
19 /// often are not, to make it easier to distinguish between them. [`Result`] is
20 /// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias
21 /// will generally use `io::Result` instead of shadowing the [prelude]'s import
22 /// of [`std::result::Result`][`Result`].
23 ///
24 /// [`std::io`]: crate::io
25 /// [`io::Error`]: Error
26 /// [`Result`]: crate::result::Result
27 /// [prelude]: crate::prelude
28 ///
29 /// # Examples
30 ///
31 /// A convenience function that bubbles an `io::Result` to its caller:
32 ///
33 /// ```
34 /// use std::io;
35 ///
36 /// fn get_string() -> io::Result<String> {
37 /// let mut buffer = String::new();
38 ///
39 /// io::stdin().read_line(&mut buffer)?;
40 ///
41 /// Ok(buffer)
42 /// }
43 /// ```
44 #[stable(feature = "rust1", since = "1.0.0")]
45 pub type Result<T> = result::Result<T, Error>;
46
47 /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
48 /// associated traits.
49 ///
50 /// Errors mostly originate from the underlying OS, but custom instances of
51 /// `Error` can be created with crafted error messages and a particular value of
52 /// [`ErrorKind`].
53 ///
54 /// [`Read`]: crate::io::Read
55 /// [`Write`]: crate::io::Write
56 /// [`Seek`]: crate::io::Seek
57 #[stable(feature = "rust1", since = "1.0.0")]
58 pub struct Error {
59 repr: Repr,
60 }
61
62 #[stable(feature = "rust1", since = "1.0.0")]
63 impl fmt::Debug for Error {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 fmt::Debug::fmt(&self.repr, f)
66 }
67 }
68
69 enum Repr {
70 Os(i32),
71 Simple(ErrorKind),
72 // &str is a fat pointer, but &&str is a thin pointer.
73 SimpleMessage(ErrorKind, &'static &'static str),
74 Custom(Box<Custom>),
75 }
76
77 #[derive(Debug)]
78 struct Custom {
79 kind: ErrorKind,
80 error: Box<dyn error::Error + Send + Sync>,
81 }
82
83 /// A list specifying general categories of I/O error.
84 ///
85 /// This list is intended to grow over time and it is not recommended to
86 /// exhaustively match against it.
87 ///
88 /// It is used with the [`io::Error`] type.
89 ///
90 /// [`io::Error`]: Error
91 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
92 #[stable(feature = "rust1", since = "1.0.0")]
93 #[allow(deprecated)]
94 #[non_exhaustive]
95 pub enum ErrorKind {
96 /// An entity was not found, often a file.
97 #[stable(feature = "rust1", since = "1.0.0")]
98 NotFound,
99 /// The operation lacked the necessary privileges to complete.
100 #[stable(feature = "rust1", since = "1.0.0")]
101 PermissionDenied,
102 /// The connection was refused by the remote server.
103 #[stable(feature = "rust1", since = "1.0.0")]
104 ConnectionRefused,
105 /// The connection was reset by the remote server.
106 #[stable(feature = "rust1", since = "1.0.0")]
107 ConnectionReset,
108 /// The remote host is not reachable.
109 #[unstable(feature = "io_error_more", issue = "86442")]
110 HostUnreachable,
111 /// The network containing the remote host is not reachable.
112 #[unstable(feature = "io_error_more", issue = "86442")]
113 NetworkUnreachable,
114 /// The connection was aborted (terminated) by the remote server.
115 #[stable(feature = "rust1", since = "1.0.0")]
116 ConnectionAborted,
117 /// The network operation failed because it was not connected yet.
118 #[stable(feature = "rust1", since = "1.0.0")]
119 NotConnected,
120 /// A socket address could not be bound because the address is already in
121 /// use elsewhere.
122 #[stable(feature = "rust1", since = "1.0.0")]
123 AddrInUse,
124 /// A nonexistent interface was requested or the requested address was not
125 /// local.
126 #[stable(feature = "rust1", since = "1.0.0")]
127 AddrNotAvailable,
128 /// The system's networking is down.
129 #[unstable(feature = "io_error_more", issue = "86442")]
130 NetworkDown,
131 /// The operation failed because a pipe was closed.
132 #[stable(feature = "rust1", since = "1.0.0")]
133 BrokenPipe,
134 /// An entity already exists, often a file.
135 #[stable(feature = "rust1", since = "1.0.0")]
136 AlreadyExists,
137 /// The operation needs to block to complete, but the blocking operation was
138 /// requested to not occur.
139 #[stable(feature = "rust1", since = "1.0.0")]
140 WouldBlock,
141 /// A filesystem object is, unexpectedly, not a directory.
142 ///
143 /// For example, a filesystem path was specified where one of the intermediate directory
144 /// components was, in fact, a plain file.
145 #[unstable(feature = "io_error_more", issue = "86442")]
146 NotADirectory,
147 /// The filesystem object is, unexpectedly, a directory.
148 ///
149 /// A directory was specified when a non-directory was expected.
150 #[unstable(feature = "io_error_more", issue = "86442")]
151 IsADirectory,
152 /// A non-empty directory was specified where an empty directory was expected.
153 #[unstable(feature = "io_error_more", issue = "86442")]
154 DirectoryNotEmpty,
155 /// The filesystem or storage medium is read-only, but a write operation was attempted.
156 #[unstable(feature = "io_error_more", issue = "86442")]
157 ReadOnlyFilesystem,
158 /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
159 ///
160 /// There was a loop (or excessively long chain) resolving a filesystem object
161 /// or file IO object.
162 ///
163 /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
164 /// system-specific limit on the depth of symlink traversal.
165 #[unstable(feature = "io_error_more", issue = "86442")]
166 FilesystemLoop,
167 /// Stale network file handle.
168 ///
169 /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
170 /// by problems with the network or server.
171 #[unstable(feature = "io_error_more", issue = "86442")]
172 StaleNetworkFileHandle,
173 /// A parameter was incorrect.
174 #[stable(feature = "rust1", since = "1.0.0")]
175 InvalidInput,
176 /// Data not valid for the operation were encountered.
177 ///
178 /// Unlike [`InvalidInput`], this typically means that the operation
179 /// parameters were valid, however the error was caused by malformed
180 /// input data.
181 ///
182 /// For example, a function that reads a file into a string will error with
183 /// `InvalidData` if the file's contents are not valid UTF-8.
184 ///
185 /// [`InvalidInput`]: ErrorKind::InvalidInput
186 #[stable(feature = "io_invalid_data", since = "1.2.0")]
187 InvalidData,
188 /// The I/O operation's timeout expired, causing it to be canceled.
189 #[stable(feature = "rust1", since = "1.0.0")]
190 TimedOut,
191 /// An error returned when an operation could not be completed because a
192 /// call to [`write`] returned [`Ok(0)`].
193 ///
194 /// This typically means that an operation could only succeed if it wrote a
195 /// particular number of bytes but only a smaller number of bytes could be
196 /// written.
197 ///
198 /// [`write`]: crate::io::Write::write
199 /// [`Ok(0)`]: Ok
200 #[stable(feature = "rust1", since = "1.0.0")]
201 WriteZero,
202 /// The underlying storage (typically, a filesystem) is full.
203 ///
204 /// This does not include out of quota errors.
205 #[unstable(feature = "io_error_more", issue = "86442")]
206 StorageFull,
207 /// Seek on unseekable file.
208 ///
209 /// Seeking was attempted on an open file handle which is not suitable for seeking - for
210 /// example, on Unix, a named pipe opened with `File::open`.
211 #[unstable(feature = "io_error_more", issue = "86442")]
212 NotSeekable,
213 /// Filesystem quota was exceeded.
214 #[unstable(feature = "io_error_more", issue = "86442")]
215 FilesystemQuotaExceeded,
216 /// File larger than allowed or supported.
217 ///
218 /// This might arise from a hard limit of the underlying filesystem or file access API, or from
219 /// an administratively imposed resource limitation. Simple disk full, and out of quota, have
220 /// their own errors.
221 #[unstable(feature = "io_error_more", issue = "86442")]
222 FileTooLarge,
223 /// Resource is busy.
224 #[unstable(feature = "io_error_more", issue = "86442")]
225 ResourceBusy,
226 /// Executable file is busy.
227 ///
228 /// An attempt was made to write to a file which is also in use as a running program. (Not all
229 /// operating systems detect this situation.)
230 #[unstable(feature = "io_error_more", issue = "86442")]
231 ExecutableFileBusy,
232 /// Deadlock (avoided).
233 ///
234 /// A file locking operation would result in deadlock. This situation is typically detected, if
235 /// at all, on a best-effort basis.
236 #[unstable(feature = "io_error_more", issue = "86442")]
237 Deadlock,
238 /// Cross-device or cross-filesystem (hard) link or rename.
239 #[unstable(feature = "io_error_more", issue = "86442")]
240 CrossesDevices,
241 /// Too many (hard) links to the same filesystem object.
242 ///
243 /// The filesystem does not support making so many hardlinks to the same file.
244 #[unstable(feature = "io_error_more", issue = "86442")]
245 TooManyLinks,
246 /// Filename too long.
247 ///
248 /// The limit might be from the underlying filesystem or API, or an administratively imposed
249 /// resource limit.
250 #[unstable(feature = "io_error_more", issue = "86442")]
251 FilenameTooLong,
252 /// Program argument list too long.
253 ///
254 /// When trying to run an external program, a system or process limit on the size of the
255 /// arguments would have been exceeded.
256 #[unstable(feature = "io_error_more", issue = "86442")]
257 ArgumentListTooLong,
258 /// This operation was interrupted.
259 ///
260 /// Interrupted operations can typically be retried.
261 #[stable(feature = "rust1", since = "1.0.0")]
262 Interrupted,
263
264 /// This operation is unsupported on this platform.
265 ///
266 /// This means that the operation can never succeed.
267 #[stable(feature = "unsupported_error", since = "1.53.0")]
268 Unsupported,
269
270 // ErrorKinds which are primarily categorisations for OS error
271 // codes should be added above.
272 //
273 /// An error returned when an operation could not be completed because an
274 /// "end of file" was reached prematurely.
275 ///
276 /// This typically means that an operation could only succeed if it read a
277 /// particular number of bytes but only a smaller number of bytes could be
278 /// read.
279 #[stable(feature = "read_exact", since = "1.6.0")]
280 UnexpectedEof,
281
282 /// An operation could not be completed, because it failed
283 /// to allocate enough memory.
284 #[stable(feature = "out_of_memory_error", since = "1.54.0")]
285 OutOfMemory,
286
287 // "Unusual" error kinds which do not correspond simply to (sets
288 // of) OS error codes, should be added just above this comment.
289 // `Other` and `Uncategorised` should remain at the end:
290 //
291 /// A custom error that does not fall under any other I/O error kind.
292 ///
293 /// This can be used to construct your own [`Error`]s that do not match any
294 /// [`ErrorKind`].
295 ///
296 /// This [`ErrorKind`] is not used by the standard library.
297 ///
298 /// Errors from the standard library that do not fall under any of the I/O
299 /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
300 /// New [`ErrorKind`]s might be added in the future for some of those.
301 #[stable(feature = "rust1", since = "1.0.0")]
302 Other,
303
304 /// Any I/O error from the standard library that's not part of this list.
305 ///
306 /// Errors that are `Uncategorized` now may move to a different or a new
307 /// [`ErrorKind`] variant in the future. It is not recommended to match
308 /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
309 #[unstable(feature = "io_error_uncategorized", issue = "none")]
310 #[doc(hidden)]
311 Uncategorized,
312 }
313
314 impl ErrorKind {
as_str(&self) -> &'static str315 pub(crate) fn as_str(&self) -> &'static str {
316 use ErrorKind::*;
317 // Strictly alphabetical, please. (Sadly rustfmt cannot do this yet.)
318 match *self {
319 AddrInUse => "address in use",
320 AddrNotAvailable => "address not available",
321 AlreadyExists => "entity already exists",
322 ArgumentListTooLong => "argument list too long",
323 BrokenPipe => "broken pipe",
324 ConnectionAborted => "connection aborted",
325 ConnectionRefused => "connection refused",
326 ConnectionReset => "connection reset",
327 CrossesDevices => "cross-device link or rename",
328 Deadlock => "deadlock",
329 DirectoryNotEmpty => "directory not empty",
330 ExecutableFileBusy => "executable file busy",
331 FileTooLarge => "file too large",
332 FilenameTooLong => "filename too long",
333 FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
334 FilesystemQuotaExceeded => "filesystem quota exceeded",
335 HostUnreachable => "host unreachable",
336 Interrupted => "operation interrupted",
337 InvalidData => "invalid data",
338 InvalidInput => "invalid input parameter",
339 IsADirectory => "is a directory",
340 NetworkDown => "network down",
341 NetworkUnreachable => "network unreachable",
342 NotADirectory => "not a directory",
343 NotConnected => "not connected",
344 NotFound => "entity not found",
345 NotSeekable => "seek on unseekable file",
346 Other => "other error",
347 OutOfMemory => "out of memory",
348 PermissionDenied => "permission denied",
349 ReadOnlyFilesystem => "read-only filesystem or storage medium",
350 ResourceBusy => "resource busy",
351 StaleNetworkFileHandle => "stale network file handle",
352 StorageFull => "no storage space",
353 TimedOut => "timed out",
354 TooManyLinks => "too many links",
355 Uncategorized => "uncategorized error",
356 UnexpectedEof => "unexpected end of file",
357 Unsupported => "unsupported",
358 WouldBlock => "operation would block",
359 WriteZero => "write zero",
360 }
361 }
362 }
363
364 /// Intended for use for errors not exposed to the user, where allocating onto
365 /// the heap (for normal construction via Error::new) is too costly.
366 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
367 impl From<ErrorKind> for Error {
368 /// Converts an [`ErrorKind`] into an [`Error`].
369 ///
370 /// This conversion allocates a new error with a simple representation of error kind.
371 ///
372 /// # Examples
373 ///
374 /// ```
375 /// use std::io::{Error, ErrorKind};
376 ///
377 /// let not_found = ErrorKind::NotFound;
378 /// let error = Error::from(not_found);
379 /// assert_eq!("entity not found", format!("{}", error));
380 /// ```
381 #[inline]
from(kind: ErrorKind) -> Error382 fn from(kind: ErrorKind) -> Error {
383 Error { repr: Repr::Simple(kind) }
384 }
385 }
386
387 impl Error {
388 /// Creates a new I/O error from a known kind of error as well as an
389 /// arbitrary error payload.
390 ///
391 /// This function is used to generically create I/O errors which do not
392 /// originate from the OS itself. The `error` argument is an arbitrary
393 /// payload which will be contained in this [`Error`].
394 ///
395 /// If no extra payload is required, use the `From` conversion from
396 /// `ErrorKind`.
397 ///
398 /// # Examples
399 ///
400 /// ```
401 /// use std::io::{Error, ErrorKind};
402 ///
403 /// // errors can be created from strings
404 /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
405 ///
406 /// // errors can also be created from other errors
407 /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
408 ///
409 /// // creating an error without payload
410 /// let eof_error = Error::from(ErrorKind::UnexpectedEof);
411 /// ```
412 #[stable(feature = "rust1", since = "1.0.0")]
new<E>(kind: ErrorKind, error: E) -> Error where E: Into<Box<dyn error::Error + Send + Sync>>,413 pub fn new<E>(kind: ErrorKind, error: E) -> Error
414 where
415 E: Into<Box<dyn error::Error + Send + Sync>>,
416 {
417 Self::_new(kind, error.into())
418 }
419
_new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error420 fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
421 Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
422 }
423
424 /// Creates a new I/O error from a known kind of error as well as a
425 /// constant message.
426 ///
427 /// This function does not allocate.
428 ///
429 /// This function should maybe change to
430 /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
431 /// in the future, when const generics allow that.
432 #[inline]
new_const(kind: ErrorKind, message: &'static &'static str) -> Error433 pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
434 Self { repr: Repr::SimpleMessage(kind, message) }
435 }
436
437 /// Returns an error representing the last OS error which occurred.
438 ///
439 /// This function reads the value of `errno` for the target platform (e.g.
440 /// `GetLastError` on Windows) and will return a corresponding instance of
441 /// [`Error`] for the error code.
442 ///
443 /// # Examples
444 ///
445 /// ```
446 /// use std::io::Error;
447 ///
448 /// println!("last OS error: {:?}", Error::last_os_error());
449 /// ```
450 #[stable(feature = "rust1", since = "1.0.0")]
451 #[must_use]
452 #[inline]
last_os_error() -> Error453 pub fn last_os_error() -> Error {
454 Error::from_raw_os_error(sys::os::errno() as i32)
455 }
456
457 /// Creates a new instance of an [`Error`] from a particular OS error code.
458 ///
459 /// # Examples
460 ///
461 /// On Linux:
462 ///
463 /// ```
464 /// # if cfg!(target_os = "linux") {
465 /// use std::io;
466 ///
467 /// let error = io::Error::from_raw_os_error(22);
468 /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
469 /// # }
470 /// ```
471 ///
472 /// On Windows:
473 ///
474 /// ```
475 /// # if cfg!(windows) {
476 /// use std::io;
477 ///
478 /// let error = io::Error::from_raw_os_error(10022);
479 /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
480 /// # }
481 /// ```
482 #[stable(feature = "rust1", since = "1.0.0")]
483 #[must_use]
484 #[inline]
from_raw_os_error(code: i32) -> Error485 pub fn from_raw_os_error(code: i32) -> Error {
486 Error { repr: Repr::Os(code) }
487 }
488
489 /// Returns the OS error that this error represents (if any).
490 ///
491 /// If this [`Error`] was constructed via [`last_os_error`] or
492 /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
493 /// it will return [`None`].
494 ///
495 /// [`last_os_error`]: Error::last_os_error
496 /// [`from_raw_os_error`]: Error::from_raw_os_error
497 ///
498 /// # Examples
499 ///
500 /// ```
501 /// use std::io::{Error, ErrorKind};
502 ///
503 /// fn print_os_error(err: &Error) {
504 /// if let Some(raw_os_err) = err.raw_os_error() {
505 /// println!("raw OS error: {:?}", raw_os_err);
506 /// } else {
507 /// println!("Not an OS error");
508 /// }
509 /// }
510 ///
511 /// fn main() {
512 /// // Will print "raw OS error: ...".
513 /// print_os_error(&Error::last_os_error());
514 /// // Will print "Not an OS error".
515 /// print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
516 /// }
517 /// ```
518 #[stable(feature = "rust1", since = "1.0.0")]
519 #[must_use]
520 #[inline]
raw_os_error(&self) -> Option<i32>521 pub fn raw_os_error(&self) -> Option<i32> {
522 match self.repr {
523 Repr::Os(i) => Some(i),
524 Repr::Custom(..) => None,
525 Repr::Simple(..) => None,
526 Repr::SimpleMessage(..) => None,
527 }
528 }
529
530 /// Returns a reference to the inner error wrapped by this error (if any).
531 ///
532 /// If this [`Error`] was constructed via [`new`] then this function will
533 /// return [`Some`], otherwise it will return [`None`].
534 ///
535 /// [`new`]: Error::new
536 ///
537 /// # Examples
538 ///
539 /// ```
540 /// use std::io::{Error, ErrorKind};
541 ///
542 /// fn print_error(err: &Error) {
543 /// if let Some(inner_err) = err.get_ref() {
544 /// println!("Inner error: {:?}", inner_err);
545 /// } else {
546 /// println!("No inner error");
547 /// }
548 /// }
549 ///
550 /// fn main() {
551 /// // Will print "No inner error".
552 /// print_error(&Error::last_os_error());
553 /// // Will print "Inner error: ...".
554 /// print_error(&Error::new(ErrorKind::Other, "oh no!"));
555 /// }
556 /// ```
557 #[stable(feature = "io_error_inner", since = "1.3.0")]
558 #[must_use]
559 #[inline]
get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)>560 pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
561 match self.repr {
562 Repr::Os(..) => None,
563 Repr::Simple(..) => None,
564 Repr::SimpleMessage(..) => None,
565 Repr::Custom(ref c) => Some(&*c.error),
566 }
567 }
568
569 /// Returns a mutable reference to the inner error wrapped by this error
570 /// (if any).
571 ///
572 /// If this [`Error`] was constructed via [`new`] then this function will
573 /// return [`Some`], otherwise it will return [`None`].
574 ///
575 /// [`new`]: Error::new
576 ///
577 /// # Examples
578 ///
579 /// ```
580 /// use std::io::{Error, ErrorKind};
581 /// use std::{error, fmt};
582 /// use std::fmt::Display;
583 ///
584 /// #[derive(Debug)]
585 /// struct MyError {
586 /// v: String,
587 /// }
588 ///
589 /// impl MyError {
590 /// fn new() -> MyError {
591 /// MyError {
592 /// v: "oh no!".to_string()
593 /// }
594 /// }
595 ///
596 /// fn change_message(&mut self, new_message: &str) {
597 /// self.v = new_message.to_string();
598 /// }
599 /// }
600 ///
601 /// impl error::Error for MyError {}
602 ///
603 /// impl Display for MyError {
604 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
605 /// write!(f, "MyError: {}", &self.v)
606 /// }
607 /// }
608 ///
609 /// fn change_error(mut err: Error) -> Error {
610 /// if let Some(inner_err) = err.get_mut() {
611 /// inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
612 /// }
613 /// err
614 /// }
615 ///
616 /// fn print_error(err: &Error) {
617 /// if let Some(inner_err) = err.get_ref() {
618 /// println!("Inner error: {}", inner_err);
619 /// } else {
620 /// println!("No inner error");
621 /// }
622 /// }
623 ///
624 /// fn main() {
625 /// // Will print "No inner error".
626 /// print_error(&change_error(Error::last_os_error()));
627 /// // Will print "Inner error: ...".
628 /// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
629 /// }
630 /// ```
631 #[stable(feature = "io_error_inner", since = "1.3.0")]
632 #[must_use]
633 #[inline]
get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)>634 pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
635 match self.repr {
636 Repr::Os(..) => None,
637 Repr::Simple(..) => None,
638 Repr::SimpleMessage(..) => None,
639 Repr::Custom(ref mut c) => Some(&mut *c.error),
640 }
641 }
642
643 /// Consumes the `Error`, returning its inner error (if any).
644 ///
645 /// If this [`Error`] was constructed via [`new`] then this function will
646 /// return [`Some`], otherwise it will return [`None`].
647 ///
648 /// [`new`]: Error::new
649 ///
650 /// # Examples
651 ///
652 /// ```
653 /// use std::io::{Error, ErrorKind};
654 ///
655 /// fn print_error(err: Error) {
656 /// if let Some(inner_err) = err.into_inner() {
657 /// println!("Inner error: {}", inner_err);
658 /// } else {
659 /// println!("No inner error");
660 /// }
661 /// }
662 ///
663 /// fn main() {
664 /// // Will print "No inner error".
665 /// print_error(Error::last_os_error());
666 /// // Will print "Inner error: ...".
667 /// print_error(Error::new(ErrorKind::Other, "oh no!"));
668 /// }
669 /// ```
670 #[stable(feature = "io_error_inner", since = "1.3.0")]
671 #[must_use = "`self` will be dropped if the result is not used"]
672 #[inline]
into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>>673 pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
674 match self.repr {
675 Repr::Os(..) => None,
676 Repr::Simple(..) => None,
677 Repr::SimpleMessage(..) => None,
678 Repr::Custom(c) => Some(c.error),
679 }
680 }
681
682 /// Returns the corresponding [`ErrorKind`] for this error.
683 ///
684 /// # Examples
685 ///
686 /// ```
687 /// use std::io::{Error, ErrorKind};
688 ///
689 /// fn print_error(err: Error) {
690 /// println!("{:?}", err.kind());
691 /// }
692 ///
693 /// fn main() {
694 /// // Will print "Uncategorized".
695 /// print_error(Error::last_os_error());
696 /// // Will print "AddrInUse".
697 /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
698 /// }
699 /// ```
700 #[stable(feature = "rust1", since = "1.0.0")]
701 #[must_use]
702 #[inline]
kind(&self) -> ErrorKind703 pub fn kind(&self) -> ErrorKind {
704 match self.repr {
705 Repr::Os(code) => sys::decode_error_kind(code),
706 Repr::Custom(ref c) => c.kind,
707 Repr::Simple(kind) => kind,
708 Repr::SimpleMessage(kind, _) => kind,
709 }
710 }
711 }
712
713 impl fmt::Debug for Repr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result714 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
715 match *self {
716 Repr::Os(code) => fmt
717 .debug_struct("Os")
718 .field("code", &code)
719 .field("kind", &sys::decode_error_kind(code))
720 .field("message", &sys::os::error_string(code))
721 .finish(),
722 Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
723 Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
724 Repr::SimpleMessage(kind, &message) => {
725 fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
726 }
727 }
728 }
729 }
730
731 #[stable(feature = "rust1", since = "1.0.0")]
732 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result733 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
734 match self.repr {
735 Repr::Os(code) => {
736 let detail = sys::os::error_string(code);
737 write!(fmt, "{} (os error {})", detail, code)
738 }
739 Repr::Custom(ref c) => c.error.fmt(fmt),
740 Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
741 Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
742 }
743 }
744 }
745
746 #[stable(feature = "rust1", since = "1.0.0")]
747 impl error::Error for Error {
748 #[allow(deprecated, deprecated_in_future)]
description(&self) -> &str749 fn description(&self) -> &str {
750 match self.repr {
751 Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
752 Repr::SimpleMessage(_, &msg) => msg,
753 Repr::Custom(ref c) => c.error.description(),
754 }
755 }
756
757 #[allow(deprecated)]
cause(&self) -> Option<&dyn error::Error>758 fn cause(&self) -> Option<&dyn error::Error> {
759 match self.repr {
760 Repr::Os(..) => None,
761 Repr::Simple(..) => None,
762 Repr::SimpleMessage(..) => None,
763 Repr::Custom(ref c) => c.error.cause(),
764 }
765 }
766
source(&self) -> Option<&(dyn error::Error + 'static)>767 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
768 match self.repr {
769 Repr::Os(..) => None,
770 Repr::Simple(..) => None,
771 Repr::SimpleMessage(..) => None,
772 Repr::Custom(ref c) => c.error.source(),
773 }
774 }
775 }
776
_assert_error_is_sync_send()777 fn _assert_error_is_sync_send() {
778 fn _is_sync_send<T: Sync + Send>() {}
779 _is_sync_send::<Error>();
780 }
781