1use thiserror::Error;
6
7#[derive(Eq, Error, Clone, Debug, PartialEq)]
8pub enum FxfsError {
9 #[error("Already exists")]
10 AlreadyExists,
11 #[error("Filesystem inconsistency")]
12 Inconsistent,
13 #[error("Internal error")]
14 Internal,
15 #[error("Expected directory")]
16 NotDir,
17 #[error("Expected file")]
18 NotFile,
19 #[error("Not found")]
20 NotFound,
21 #[error("Not empty")]
22 NotEmpty,
23 #[error("Read only filesystem")]
24 ReadOnlyFilesystem,
25 #[error("No space")]
26 NoSpace,
27 #[error("Deleted")]
28 Deleted,
29 #[error("Invalid arguments")]
30 InvalidArgs,
31 #[error("Too big")]
32 TooBig,
33 #[error("Invalid version")]
34 InvalidVersion,
35 #[error("Journal flush error")]
36 JournalFlushError,
37 #[error("Not supported")]
38 NotSupported,
39 #[error("Access denied")]
40 AccessDenied,
41 #[error("Out of range")]
42 OutOfRange,
43 #[error("Already bound")]
44 AlreadyBound,
45 #[error("Bad path")]
46 BadPath,
47 #[error("Wrong type")]
48 WrongType,
49 #[error("Data integrity error")]
50 IntegrityError,
51 #[error("Unavailable")]
52 Unavailable,
53 #[error("No key")]
54 NoKey,
55}
56
57impl FxfsError {
58 pub fn matches(&self, error: &anyhow::Error) -> bool {
70 if let Some(root_cause) = error.root_cause().downcast_ref::<FxfsError>() {
71 self == root_cause
72 } else {
73 false
74 }
75 }
76}
77
78#[cfg(target_os = "fuchsia")]
79mod fuchsia {
80 use super::*;
81 use zx::Status;
82
83 impl From<FxfsError> for Status {
84 fn from(err: FxfsError) -> Status {
85 match err {
86 FxfsError::AlreadyExists => Status::ALREADY_EXISTS,
87 FxfsError::Inconsistent => Status::IO_DATA_INTEGRITY,
88 FxfsError::Internal => Status::INTERNAL,
89 FxfsError::NotDir => Status::NOT_DIR,
90 FxfsError::NotFile => Status::NOT_FILE,
91 FxfsError::NotFound => Status::NOT_FOUND,
92 FxfsError::NotEmpty => Status::NOT_EMPTY,
93 FxfsError::ReadOnlyFilesystem => Status::ACCESS_DENIED,
94 FxfsError::NoSpace => Status::NO_SPACE,
95 FxfsError::Deleted => Status::ACCESS_DENIED,
96 FxfsError::InvalidArgs => Status::INVALID_ARGS,
97 FxfsError::TooBig => Status::FILE_BIG,
98 FxfsError::InvalidVersion => Status::NOT_SUPPORTED,
99 FxfsError::JournalFlushError => Status::IO,
100 FxfsError::NotSupported => Status::NOT_SUPPORTED,
101 FxfsError::AccessDenied => Status::ACCESS_DENIED,
102 FxfsError::OutOfRange => Status::OUT_OF_RANGE,
103 FxfsError::AlreadyBound => Status::ALREADY_BOUND,
104 FxfsError::BadPath => Status::BAD_PATH,
105 FxfsError::WrongType => Status::WRONG_TYPE,
106 FxfsError::IntegrityError => Status::IO_DATA_INTEGRITY,
107 FxfsError::Unavailable => Status::UNAVAILABLE,
108 FxfsError::NoKey => Status::ACCESS_DENIED,
109 }
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::FxfsError;
117 use anyhow::{anyhow, Context};
118
119 #[test]
120 fn test_matches() {
121 let err: anyhow::Error = FxfsError::AlreadyBound.into();
123 let result: Result<(), anyhow::Error> = Err(err);
124 let result = result.context("Foo");
125 let err = result.err().unwrap();
126 assert!(FxfsError::AlreadyBound.matches(&err));
127
128 let err = anyhow!(FxfsError::AlreadyBound).context("Foo");
130 assert!(FxfsError::AlreadyBound.matches(&err));
131
132 let err = anyhow!(anyhow!(FxfsError::AlreadyBound).context("Foo"));
135 assert!(FxfsError::AlreadyBound.matches(&err));
136 }
137}