1use 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#[derive(Debug)]
15pub enum Error<P> {
16 Io(P, io::Error),
18 Parse(P, Box<dyn error::Error + Send + Sync>),
20 Write(P, Box<dyn error::Error + Send + Sync>),
22 Serde(P, Box<dyn error::Error + Send + Sync>),
24
25 UnexpectedNumberOfChildren {
27 expected: &'static str,
29 found: usize,
31 path: P,
33 },
34}
35
36impl<P: fmt::Debug> error::Error for Error<P> {
37 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
38 match self {
39 Self::Io(_, e) => Some(e),
40 Self::Parse(_, e) => Some(e.as_ref()),
41 Self::Write(_, e) => Some(e.as_ref()),
42 Self::Serde(_, e) => Some(e.as_ref()),
43 Self::UnexpectedNumberOfChildren { .. } => None,
44 }
45 }
46}
47
48impl<P: fmt::Debug> fmt::Display for Error<P> {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 Self::Io(path, e) => write!(f, "IO error at {:?}: {}", path, e),
52 Self::Parse(path, e) => write!(f, "Parse error at {:?}: {}", path, e),
53 Self::Write(path, e) => write!(f, "Write error at {:?}: {}", path, e),
54 Self::Serde(path, e) => write!(f, "Serde error at {:?}: {}", path, e),
55 Self::UnexpectedNumberOfChildren {
56 expected,
57 found,
58 path,
59 } => write!(
60 f,
61 "Unexpected number of children: expected {}, found {} at {:?}",
62 expected, found, path
63 ),
64 }
65 }
66}
67
68mod sealed {
69 use std::io;
70
71 pub trait Sealed {}
72
73 impl<T> Sealed for io::Result<T> {}
74}
75
76pub trait WrapIoError<PathType: vfs::PathType + ?Sized>: Sized + sealed::Sealed {
78 type Output;
80
81 fn wrap_io_error(
83 self,
84 get_path: impl FnOnce() -> PathType::OwnedPath,
85 ) -> Result<Self::Output, PathType::OwnedPath>;
86
87 fn wrap_io_error_with(self, path: &PathType) -> Result<Self::Output, PathType::OwnedPath> {
89 self.wrap_io_error(|| path.owned())
90 }
91}
92
93impl<T, P: vfs::PathType + ?Sized> WrapIoError<P> for io::Result<T> {
94 type Output = T;
95
96 fn wrap_io_error(
97 self,
98 get_path: impl FnOnce() -> P::OwnedPath,
99 ) -> Result<Self::Output, P::OwnedPath> {
100 self.map_err(|e| Error::Io(get_path(), e))
101 }
102}
103
104#[expect(type_alias_bounds)]
108pub type Result<T, P: OwnedPathType> = result::Result<T, Error<P>>;
109
110#[expect(type_alias_bounds)]
112pub type VfsResult<T, Vfs: VfsCore> = Result<T, <Vfs::Path as PathType>::OwnedPath>;