async_walkdir/
error.rs

1// SPDX-FileCopyrightText: 2020-2024 Ririsoft <riri@ririsoft.com>
2// SPDX-FileCopyrightText: 2024 Jordan Danford <jordandanford@gmail.com>
3// SPDX-License-Identifier: Apache-2.0
4
5use std::{
6    io,
7    path::{Path, PathBuf},
8};
9
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13#[error(transparent)]
14/// An error produced during a directory tree traversal.
15pub struct Error(#[from] InnerError);
16
17impl Error {
18    /// Returns the path where the error occured if it applies,
19    /// for instance during IO operations.
20    pub fn path(&self) -> Option<&Path> {
21        let InnerError::Io { ref path, .. } = self.0;
22        Some(path)
23    }
24
25    /// Returns the original [`io::Error`] if any.
26    pub fn io(&self) -> Option<&io::Error> {
27        let InnerError::Io { ref source, .. } = self.0;
28        Some(source)
29    }
30
31    /// Similar to [`io`][Self::io] except consumes self to convert to the original
32    /// [`io::Error`] if one exists.
33    pub fn into_io(self) -> Option<io::Error> {
34        let InnerError::Io { source, .. } = self.0;
35        Some(source)
36    }
37}
38
39impl From<Error> for io::Error {
40    /// Convert to an [`io::Error`], preserving the original [`struct@Error`]
41    /// as the ["inner error"][io::Error::into_inner].
42    /// Note that this also makes the display of the error include the context.
43    ///
44    /// This is different from [`into_io`][Error::into_io] which returns
45    /// the original [`io::Error`].
46    fn from(err: Error) -> io::Error {
47        let InnerError::Io { ref source, .. } = err.0;
48        io::Error::new(source.kind(), err)
49    }
50}
51
52#[derive(Debug, Error)]
53pub enum InnerError {
54    #[error("IO error at '{path}': {source}")]
55    /// A error produced during an IO operation.
56    Io {
57        /// The path in the directory tree where the IO error occured.
58        path: PathBuf,
59        /// The IO error.
60        source: io::Error,
61    },
62}