]> git.proxmox.com Git - rustc.git/blob - library/std/src/io/error.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / library / std / src / io / error.rs
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 {
64 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 /// A custom error that does not fall under any other I/O error kind.
265 ///
266 /// This can be used to construct your own [`Error`]s that do not match any
267 /// [`ErrorKind`].
268 ///
269 /// This [`ErrorKind`] is not used by the standard library.
270 ///
271 /// Errors from the standard library that do not fall under any of the I/O
272 /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
273 /// New [`ErrorKind`]s might be added in the future for some of those.
274 #[stable(feature = "rust1", since = "1.0.0")]
275 Other,
276
277 /// An error returned when an operation could not be completed because an
278 /// "end of file" was reached prematurely.
279 ///
280 /// This typically means that an operation could only succeed if it read a
281 /// particular number of bytes but only a smaller number of bytes could be
282 /// read.
283 #[stable(feature = "read_exact", since = "1.6.0")]
284 UnexpectedEof,
285
286 /// This operation is unsupported on this platform.
287 ///
288 /// This means that the operation can never succeed.
289 #[stable(feature = "unsupported_error", since = "1.53.0")]
290 Unsupported,
291
292 /// An operation could not be completed, because it failed
293 /// to allocate enough memory.
294 #[stable(feature = "out_of_memory_error", since = "1.54.0")]
295 OutOfMemory,
296
297 /// Any I/O error from the standard library that's not part of this list.
298 ///
299 /// Errors that are `Uncategorized` now may move to a different or a new
300 /// [`ErrorKind`] variant in the future. It is not recommended to match
301 /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
302 #[unstable(feature = "io_error_uncategorized", issue = "none")]
303 #[doc(hidden)]
304 Uncategorized,
305 }
306
307 impl ErrorKind {
308 pub(crate) fn as_str(&self) -> &'static str {
309 use ErrorKind::*;
310 match *self {
311 AddrInUse => "address in use",
312 AddrNotAvailable => "address not available",
313 AlreadyExists => "entity already exists",
314 ArgumentListTooLong => "argument list too long",
315 BrokenPipe => "broken pipe",
316 ResourceBusy => "resource busy",
317 ConnectionAborted => "connection aborted",
318 ConnectionRefused => "connection refused",
319 ConnectionReset => "connection reset",
320 CrossesDevices => "cross-device link or rename",
321 Deadlock => "deadlock",
322 DirectoryNotEmpty => "directory not empty",
323 ExecutableFileBusy => "executable file busy",
324 FilenameTooLong => "filename too long",
325 FilesystemQuotaExceeded => "filesystem quota exceeded",
326 FileTooLarge => "file too large",
327 HostUnreachable => "host unreachable",
328 Interrupted => "operation interrupted",
329 InvalidData => "invalid data",
330 InvalidInput => "invalid input parameter",
331 IsADirectory => "is a directory",
332 NetworkDown => "network down",
333 NetworkUnreachable => "network unreachable",
334 NotADirectory => "not a directory",
335 StorageFull => "no storage space",
336 NotConnected => "not connected",
337 NotFound => "entity not found",
338 Other => "other error",
339 OutOfMemory => "out of memory",
340 PermissionDenied => "permission denied",
341 ReadOnlyFilesystem => "read-only filesystem or storage medium",
342 StaleNetworkFileHandle => "stale network file handle",
343 FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
344 NotSeekable => "seek on unseekable file",
345 TimedOut => "timed out",
346 TooManyLinks => "too many links",
347 Uncategorized => "uncategorized error",
348 UnexpectedEof => "unexpected end of file",
349 Unsupported => "unsupported",
350 WouldBlock => "operation would block",
351 WriteZero => "write zero",
352 }
353 }
354 }
355
356 /// Intended for use for errors not exposed to the user, where allocating onto
357 /// the heap (for normal construction via Error::new) is too costly.
358 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
359 impl From<ErrorKind> for Error {
360 /// Converts an [`ErrorKind`] into an [`Error`].
361 ///
362 /// This conversion allocates a new error with a simple representation of error kind.
363 ///
364 /// # Examples
365 ///
366 /// ```
367 /// use std::io::{Error, ErrorKind};
368 ///
369 /// let not_found = ErrorKind::NotFound;
370 /// let error = Error::from(not_found);
371 /// assert_eq!("entity not found", format!("{}", error));
372 /// ```
373 #[inline]
374 fn from(kind: ErrorKind) -> Error {
375 Error { repr: Repr::Simple(kind) }
376 }
377 }
378
379 impl Error {
380 /// Creates a new I/O error from a known kind of error as well as an
381 /// arbitrary error payload.
382 ///
383 /// This function is used to generically create I/O errors which do not
384 /// originate from the OS itself. The `error` argument is an arbitrary
385 /// payload which will be contained in this [`Error`].
386 ///
387 /// # Examples
388 ///
389 /// ```
390 /// use std::io::{Error, ErrorKind};
391 ///
392 /// // errors can be created from strings
393 /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
394 ///
395 /// // errors can also be created from other errors
396 /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
397 /// ```
398 #[stable(feature = "rust1", since = "1.0.0")]
399 pub fn new<E>(kind: ErrorKind, error: E) -> Error
400 where
401 E: Into<Box<dyn error::Error + Send + Sync>>,
402 {
403 Self::_new(kind, error.into())
404 }
405
406 fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
407 Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
408 }
409
410 /// Creates a new I/O error from a known kind of error as well as a
411 /// constant message.
412 ///
413 /// This function does not allocate.
414 ///
415 /// This function should maybe change to
416 /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
417 /// in the future, when const generics allow that.
418 #[inline]
419 pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
420 Self { repr: Repr::SimpleMessage(kind, message) }
421 }
422
423 /// Returns an error representing the last OS error which occurred.
424 ///
425 /// This function reads the value of `errno` for the target platform (e.g.
426 /// `GetLastError` on Windows) and will return a corresponding instance of
427 /// [`Error`] for the error code.
428 ///
429 /// # Examples
430 ///
431 /// ```
432 /// use std::io::Error;
433 ///
434 /// println!("last OS error: {:?}", Error::last_os_error());
435 /// ```
436 #[stable(feature = "rust1", since = "1.0.0")]
437 #[inline]
438 pub fn last_os_error() -> Error {
439 Error::from_raw_os_error(sys::os::errno() as i32)
440 }
441
442 /// Creates a new instance of an [`Error`] from a particular OS error code.
443 ///
444 /// # Examples
445 ///
446 /// On Linux:
447 ///
448 /// ```
449 /// # if cfg!(target_os = "linux") {
450 /// use std::io;
451 ///
452 /// let error = io::Error::from_raw_os_error(22);
453 /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
454 /// # }
455 /// ```
456 ///
457 /// On Windows:
458 ///
459 /// ```
460 /// # if cfg!(windows) {
461 /// use std::io;
462 ///
463 /// let error = io::Error::from_raw_os_error(10022);
464 /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
465 /// # }
466 /// ```
467 #[stable(feature = "rust1", since = "1.0.0")]
468 #[inline]
469 pub fn from_raw_os_error(code: i32) -> Error {
470 Error { repr: Repr::Os(code) }
471 }
472
473 /// Returns the OS error that this error represents (if any).
474 ///
475 /// If this [`Error`] was constructed via [`last_os_error`] or
476 /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
477 /// it will return [`None`].
478 ///
479 /// [`last_os_error`]: Error::last_os_error
480 /// [`from_raw_os_error`]: Error::from_raw_os_error
481 ///
482 /// # Examples
483 ///
484 /// ```
485 /// use std::io::{Error, ErrorKind};
486 ///
487 /// fn print_os_error(err: &Error) {
488 /// if let Some(raw_os_err) = err.raw_os_error() {
489 /// println!("raw OS error: {:?}", raw_os_err);
490 /// } else {
491 /// println!("Not an OS error");
492 /// }
493 /// }
494 ///
495 /// fn main() {
496 /// // Will print "raw OS error: ...".
497 /// print_os_error(&Error::last_os_error());
498 /// // Will print "Not an OS error".
499 /// print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
500 /// }
501 /// ```
502 #[stable(feature = "rust1", since = "1.0.0")]
503 #[inline]
504 pub fn raw_os_error(&self) -> Option<i32> {
505 match self.repr {
506 Repr::Os(i) => Some(i),
507 Repr::Custom(..) => None,
508 Repr::Simple(..) => None,
509 Repr::SimpleMessage(..) => None,
510 }
511 }
512
513 /// Returns a reference to the inner error wrapped by this error (if any).
514 ///
515 /// If this [`Error`] was constructed via [`new`] then this function will
516 /// return [`Some`], otherwise it will return [`None`].
517 ///
518 /// [`new`]: Error::new
519 ///
520 /// # Examples
521 ///
522 /// ```
523 /// use std::io::{Error, ErrorKind};
524 ///
525 /// fn print_error(err: &Error) {
526 /// if let Some(inner_err) = err.get_ref() {
527 /// println!("Inner error: {:?}", inner_err);
528 /// } else {
529 /// println!("No inner error");
530 /// }
531 /// }
532 ///
533 /// fn main() {
534 /// // Will print "No inner error".
535 /// print_error(&Error::last_os_error());
536 /// // Will print "Inner error: ...".
537 /// print_error(&Error::new(ErrorKind::Other, "oh no!"));
538 /// }
539 /// ```
540 #[stable(feature = "io_error_inner", since = "1.3.0")]
541 #[inline]
542 pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
543 match self.repr {
544 Repr::Os(..) => None,
545 Repr::Simple(..) => None,
546 Repr::SimpleMessage(..) => None,
547 Repr::Custom(ref c) => Some(&*c.error),
548 }
549 }
550
551 /// Returns a mutable reference to the inner error wrapped by this error
552 /// (if any).
553 ///
554 /// If this [`Error`] was constructed via [`new`] then this function will
555 /// return [`Some`], otherwise it will return [`None`].
556 ///
557 /// [`new`]: Error::new
558 ///
559 /// # Examples
560 ///
561 /// ```
562 /// use std::io::{Error, ErrorKind};
563 /// use std::{error, fmt};
564 /// use std::fmt::Display;
565 ///
566 /// #[derive(Debug)]
567 /// struct MyError {
568 /// v: String,
569 /// }
570 ///
571 /// impl MyError {
572 /// fn new() -> MyError {
573 /// MyError {
574 /// v: "oh no!".to_string()
575 /// }
576 /// }
577 ///
578 /// fn change_message(&mut self, new_message: &str) {
579 /// self.v = new_message.to_string();
580 /// }
581 /// }
582 ///
583 /// impl error::Error for MyError {}
584 ///
585 /// impl Display for MyError {
586 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587 /// write!(f, "MyError: {}", &self.v)
588 /// }
589 /// }
590 ///
591 /// fn change_error(mut err: Error) -> Error {
592 /// if let Some(inner_err) = err.get_mut() {
593 /// inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
594 /// }
595 /// err
596 /// }
597 ///
598 /// fn print_error(err: &Error) {
599 /// if let Some(inner_err) = err.get_ref() {
600 /// println!("Inner error: {}", inner_err);
601 /// } else {
602 /// println!("No inner error");
603 /// }
604 /// }
605 ///
606 /// fn main() {
607 /// // Will print "No inner error".
608 /// print_error(&change_error(Error::last_os_error()));
609 /// // Will print "Inner error: ...".
610 /// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
611 /// }
612 /// ```
613 #[stable(feature = "io_error_inner", since = "1.3.0")]
614 #[inline]
615 pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
616 match self.repr {
617 Repr::Os(..) => None,
618 Repr::Simple(..) => None,
619 Repr::SimpleMessage(..) => None,
620 Repr::Custom(ref mut c) => Some(&mut *c.error),
621 }
622 }
623
624 /// Consumes the `Error`, returning its inner error (if any).
625 ///
626 /// If this [`Error`] was constructed via [`new`] then this function will
627 /// return [`Some`], otherwise it will return [`None`].
628 ///
629 /// [`new`]: Error::new
630 ///
631 /// # Examples
632 ///
633 /// ```
634 /// use std::io::{Error, ErrorKind};
635 ///
636 /// fn print_error(err: Error) {
637 /// if let Some(inner_err) = err.into_inner() {
638 /// println!("Inner error: {}", inner_err);
639 /// } else {
640 /// println!("No inner error");
641 /// }
642 /// }
643 ///
644 /// fn main() {
645 /// // Will print "No inner error".
646 /// print_error(Error::last_os_error());
647 /// // Will print "Inner error: ...".
648 /// print_error(Error::new(ErrorKind::Other, "oh no!"));
649 /// }
650 /// ```
651 #[stable(feature = "io_error_inner", since = "1.3.0")]
652 #[inline]
653 pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
654 match self.repr {
655 Repr::Os(..) => None,
656 Repr::Simple(..) => None,
657 Repr::SimpleMessage(..) => None,
658 Repr::Custom(c) => Some(c.error),
659 }
660 }
661
662 /// Returns the corresponding [`ErrorKind`] for this error.
663 ///
664 /// # Examples
665 ///
666 /// ```
667 /// use std::io::{Error, ErrorKind};
668 ///
669 /// fn print_error(err: Error) {
670 /// println!("{:?}", err.kind());
671 /// }
672 ///
673 /// fn main() {
674 /// // Will print "Uncategorized".
675 /// print_error(Error::last_os_error());
676 /// // Will print "AddrInUse".
677 /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
678 /// }
679 /// ```
680 #[stable(feature = "rust1", since = "1.0.0")]
681 #[inline]
682 pub fn kind(&self) -> ErrorKind {
683 match self.repr {
684 Repr::Os(code) => sys::decode_error_kind(code),
685 Repr::Custom(ref c) => c.kind,
686 Repr::Simple(kind) => kind,
687 Repr::SimpleMessage(kind, _) => kind,
688 }
689 }
690 }
691
692 impl fmt::Debug for Repr {
693 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
694 match *self {
695 Repr::Os(code) => fmt
696 .debug_struct("Os")
697 .field("code", &code)
698 .field("kind", &sys::decode_error_kind(code))
699 .field("message", &sys::os::error_string(code))
700 .finish(),
701 Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
702 Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
703 Repr::SimpleMessage(kind, &message) => {
704 fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
705 }
706 }
707 }
708 }
709
710 #[stable(feature = "rust1", since = "1.0.0")]
711 impl fmt::Display for Error {
712 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
713 match self.repr {
714 Repr::Os(code) => {
715 let detail = sys::os::error_string(code);
716 write!(fmt, "{} (os error {})", detail, code)
717 }
718 Repr::Custom(ref c) => c.error.fmt(fmt),
719 Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
720 Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
721 }
722 }
723 }
724
725 #[stable(feature = "rust1", since = "1.0.0")]
726 impl error::Error for Error {
727 #[allow(deprecated, deprecated_in_future)]
728 fn description(&self) -> &str {
729 match self.repr {
730 Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
731 Repr::SimpleMessage(_, &msg) => msg,
732 Repr::Custom(ref c) => c.error.description(),
733 }
734 }
735
736 #[allow(deprecated)]
737 fn cause(&self) -> Option<&dyn error::Error> {
738 match self.repr {
739 Repr::Os(..) => None,
740 Repr::Simple(..) => None,
741 Repr::SimpleMessage(..) => None,
742 Repr::Custom(ref c) => c.error.cause(),
743 }
744 }
745
746 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
747 match self.repr {
748 Repr::Os(..) => None,
749 Repr::Simple(..) => None,
750 Repr::SimpleMessage(..) => None,
751 Repr::Custom(ref c) => c.error.source(),
752 }
753 }
754 }
755
756 fn _assert_error_is_sync_send() {
757 fn _is_sync_send<T: Sync + Send>() {}
758 _is_sync_send::<Error>();
759 }