dir_structure/
error.rs

1//! Error type, see [`Error`].
2
3use std::error;
4use std::fmt;
5use std::io;
6use std::result;
7
8use crate::prelude::PathType;
9use crate::prelude::VfsCore;
10use crate::traits::vfs;
11use crate::traits::vfs::OwnedPathType;
12
13/// The error type for this library.
14#[derive(Debug)]
15pub enum Error<P> {
16    /// An IO error.
17    Io(P, io::Error),
18    /// Parse error.
19    Parse(P, Box<dyn error::Error + Send + Sync>),
20    /// Write error.
21    Write(P, Box<dyn error::Error + Send + Sync>),
22    /// Serde error.
23    Serde(P, Box<dyn error::Error + Send + Sync>),
24}
25
26impl<P: fmt::Debug> error::Error for Error<P> {
27    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
28        match self {
29            Self::Io(_, e) => Some(e),
30            Self::Parse(_, e) => Some(e.as_ref()),
31            Self::Write(_, e) => Some(e.as_ref()),
32            Self::Serde(_, e) => Some(e.as_ref()),
33        }
34    }
35}
36
37impl<P: fmt::Debug> fmt::Display for Error<P> {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match self {
40            Self::Io(path, e) => write!(f, "IO error at {:?}: {}", path, e),
41            Self::Parse(path, e) => write!(f, "Parse error at {:?}: {}", path, e),
42            Self::Write(path, e) => write!(f, "Write error at {:?}: {}", path, e),
43            Self::Serde(path, e) => write!(f, "Serde error at {:?}: {}", path, e),
44        }
45    }
46}
47
48mod sealed {
49    use std::io;
50
51    pub trait Sealed {}
52
53    impl<T> Sealed for io::Result<T> {}
54}
55
56/// A trait for wrapping IO errors with the path where they happened, turning [`std::io::Result`]s into [`crate::error::Result`]s.
57pub trait WrapIoError<PathType: vfs::PathType + ?Sized>: Sized + sealed::Sealed {
58    /// The inner type.
59    type Output;
60
61    /// Wrap the IO error with the path where it happened.
62    fn wrap_io_error(
63        self,
64        get_path: impl FnOnce() -> PathType::OwnedPath,
65    ) -> Result<Self::Output, PathType::OwnedPath>;
66
67    /// Wrap the IO error with the given path.
68    fn wrap_io_error_with(self, path: &PathType) -> Result<Self::Output, PathType::OwnedPath> {
69        self.wrap_io_error(|| path.owned())
70    }
71}
72
73impl<T, P: vfs::PathType + ?Sized> WrapIoError<P> for io::Result<T> {
74    type Output = T;
75
76    fn wrap_io_error(
77        self,
78        get_path: impl FnOnce() -> P::OwnedPath,
79    ) -> Result<Self::Output, P::OwnedPath> {
80        self.map_err(|e| Error::Io(get_path(), e))
81    }
82}
83
84/// The result type for this library.
85///
86/// See [the `Error` enum](Error) for the errors that can happen.
87#[expect(type_alias_bounds)]
88pub type Result<T, P: OwnedPathType> = result::Result<T, Error<P>>;
89
90/// A convenience result type for a specific VFS.
91#[expect(type_alias_bounds)]
92pub type VfsResult<T, Vfs: VfsCore> = Result<T, <Vfs::Path as PathType>::OwnedPath>;