1use std::fmt::Display;
2use thiserror::Error;
3
4#[derive(Error, Debug)]
5pub enum VfsError {
6 #[error("IO error: {0}")]
7 IoError(#[from] std::io::Error),
8
9 #[error("Invalid absolute path: {path}")]
10 InvalidAbsolutePath { path: String },
11
12 #[error("Invalid file: {path}")]
13 InvalidFile { path: String },
14
15 #[error("Unauthorized")]
16 Unauthorized,
17
18 #[error("Forbidden")]
19 Forbidden,
20
21 #[error("Not supported")]
22 NotSupported,
23
24 #[error("{context}, cause: {cause}")]
26 WithContext {
27 context: String,
29 #[source]
31 cause: Box<VfsError>,
32 },
33}
34
35pub type VfsResult<T> = std::result::Result<T, VfsError>;
36
37pub(crate) trait VfsResultExt<T> {
38 fn with_context<C, F>(self, f: F) -> VfsResult<T>
39 where
40 C: Display + Send + Sync + 'static,
41 F: FnOnce() -> C;
42}
43
44impl<T> VfsResultExt<T> for VfsResult<T> {
45 fn with_context<C, F>(self, context: F) -> VfsResult<T>
46 where
47 C: Display + Send + Sync + 'static,
48 F: FnOnce() -> C,
49 {
50 self.map_err(|error| VfsError::WithContext {
51 context: context().to_string(),
52 cause: Box::new(error),
53 })
54 }
55}