1use crate::SPath;
2use derive_more::{Display, From};
3use std::io;
4use std::path::Path;
5use std::time::SystemTimeError;
6
7pub type Result<T> = core::result::Result<T, Error>;
8
9#[derive(Debug, Display)]
10pub enum Error {
11 #[display("Path is not valid UTF-8: '{_0}'")]
13 PathNotUtf8(String),
14 #[display("Path has no file name: '{_0}'")]
15 PathHasNoFileName(String),
16 #[display("Strip Prefix fail. Path '{path}' does not a base of '{prefix}'")]
17 StripPrefix {
18 prefix: String,
19 path: String,
20 },
21
22 #[display("File not found at path: '{_0}'")]
24 FileNotFound(String),
25 #[display("Cannot open file '{}'\nCause: {}", _0.path, _0.cause)]
26 FileCantOpen(PathAndCause),
27 #[display("Cannot read path '{}'\nCause: {}", _0.path, _0.cause)]
28 FileCantRead(PathAndCause),
29 #[display("Cannot write file '{}'\nCause: {}", _0.path, _0.cause)]
30 FileCantWrite(PathAndCause),
31 #[display("Cannot create file '{}'\nCause: {}", _0.path, _0.cause)]
32 FileCantCreate(PathAndCause),
33 #[display("File path has no parent directory: '{_0}'")]
34 FileHasNoParent(String),
35
36 #[display("File not safe to remove.\nPath: '{}'\nCause: {}", _0.path, _0.cause)]
38 FileNotSafeToRemove(PathAndCause),
39 #[display("Directory not safe to remove.\nPath: '{}'\nCause: {}", _0.path, _0.cause)]
40 DirNotSafeToRemove(PathAndCause),
41
42 #[display("File not safe to trash.\nPath: '{}'\nCause: {}", _0.path, _0.cause)]
44 FileNotSafeToTrash(PathAndCause),
45 #[display("Directory not safe to trash.\nPath: '{}'\nCause: {}", _0.path, _0.cause)]
46 DirNotSafeToTrash(PathAndCause),
47 #[display("Cannot trash path '{}'\nCause: {}", _0.path, _0.cause)]
48 CantTrash(PathAndCause),
49
50 #[display("Cannot sort by globs.\nCause: {cause}")]
52 SortByGlobs {
53 cause: String,
54 },
55
56 #[display("Cannot get metadata for path '{}'\nCause: {}", _0.path, _0.cause)]
58 CantGetMetadata(PathAndCause),
59 #[display("Cannot get 'modified' metadata for path '{}'\nCause: {}", _0.path, _0.cause)]
60 CantGetMetadataModified(PathAndCause),
61
62 #[display("Cannot get duration from system time. Cause: {_0}")]
64 CantGetDurationSystemTimeError(SystemTimeError),
65
66 #[display("Cannot create directory (and parents) '{}'\nCause: {}", _0.path, _0.cause)]
68 DirCantCreateAll(PathAndCause),
69
70 #[display("Path is invalid: '{}'\nCause: {}",_0.path, _0.cause)]
72 PathNotValidForPath(PathAndCause),
73
74 #[display("Cannot create glob pattern '{glob}'.\nCause: {cause}")]
76 GlobCantNew {
77 glob: String,
78 cause: globset::Error,
79 },
80 #[display("Cannot build glob set from '{globs:?}'.\nCause: {cause}")]
81 GlobSetCantBuild {
82 globs: Vec<String>,
83 cause: globset::Error,
84 },
85
86 #[display("Failed to watch path '{path}'.\nCause: {cause}")]
88 FailToWatch {
89 path: String,
90 cause: String,
91 },
92 #[display("Cannot watch path because it was not found: '{_0}'")]
93 CantWatchPathNotFound(String),
94
95 SpanInvalidStartAfterEnd,
97 SpanOutOfBounds,
98 SpanInvalidUtf8,
99
100 #[display("Cannot compute relative path from '{base}' to '{path}'")]
102 CannotDiff {
103 path: String,
104 base: String,
105 },
106 #[display("Cannot Canonicalize path '{}'\nCause: {}", _0.path, _0.cause)]
107 CannotCanonicalize(PathAndCause),
108
109 #[cfg(feature = "with-json")]
111 #[display("Cannot read json path '{}'\nCause: {}", _0.path, _0.cause)]
112 JsonCantRead(PathAndCause),
113 #[cfg(feature = "with-json")]
114 #[display("Cannot write JSON to path '{}'\nCause: {}", _0.path, _0.cause)]
115 JsonCantWrite(PathAndCause),
116 #[cfg(feature = "with-json")]
117 #[display("Error processing NDJSON: {_0}")]
118 NdJson(String),
119
120 #[cfg(feature = "with-toml")]
122 #[display("Cannot read TOML from path '{}'\nCause: {}", _0.path, _0.cause)]
123 TomlCantRead(PathAndCause),
124 #[cfg(feature = "with-toml")]
125 #[display("Cannot write TOML to path '{}'\nCause: {}", _0.path, _0.cause)]
126 TomlCantWrite(PathAndCause),
127}
128
129impl Error {
130 pub fn sort_by_globs(cause: impl std::fmt::Display) -> Error {
131 Error::SortByGlobs {
132 cause: cause.to_string(),
133 }
134 }
135}
136
137#[derive(Debug, Display, From)]
140pub enum Cause {
141 #[from]
142 Custom(String),
143
144 #[from]
145 Io(Box<io::Error>),
146
147 #[cfg(feature = "with-json")]
148 SerdeJson(Box<serde_json::Error>),
149
150 #[cfg(feature = "with-toml")]
151 TomlDe(Box<toml::de::Error>),
152
153 #[cfg(feature = "with-toml")]
154 TomlSer(Box<toml::ser::Error>),
155}
156
157#[derive(Debug)]
158pub struct PathAndCause {
159 pub path: String,
160 pub cause: Cause,
161}
162
163impl From<(&Path, io::Error)> for PathAndCause {
168 fn from(val: (&Path, io::Error)) -> Self {
169 PathAndCause {
170 path: val.0.to_string_lossy().to_string(),
171 cause: Cause::Io(Box::new(val.1)),
172 }
173 }
174}
175
176impl From<(&SPath, io::Error)> for PathAndCause {
177 fn from(val: (&SPath, io::Error)) -> Self {
178 PathAndCause {
179 path: val.0.to_string(),
180 cause: Cause::Io(Box::new(val.1)),
181 }
182 }
183}
184
185impl From<(&SPath, std::time::SystemTimeError)> for PathAndCause {
187 fn from(val: (&SPath, std::time::SystemTimeError)) -> Self {
188 PathAndCause {
189 path: val.0.to_string(),
190 cause: Cause::Custom(val.1.to_string()),
191 }
192 }
193}
194
195#[cfg(feature = "with-json")]
200impl From<(&Path, serde_json::Error)> for PathAndCause {
201 fn from(val: (&Path, serde_json::Error)) -> Self {
202 PathAndCause {
203 path: val.0.to_string_lossy().to_string(),
204 cause: Cause::SerdeJson(Box::new(val.1)),
205 }
206 }
207}
208
209#[cfg(feature = "with-toml")]
214impl From<(&Path, toml::de::Error)> for PathAndCause {
215 fn from(val: (&Path, toml::de::Error)) -> Self {
216 PathAndCause {
217 path: val.0.to_string_lossy().to_string(),
218 cause: Cause::TomlDe(Box::new(val.1)),
219 }
220 }
221}
222
223#[cfg(feature = "with-toml")]
224impl From<(&Path, toml::ser::Error)> for PathAndCause {
225 fn from(val: (&Path, toml::ser::Error)) -> Self {
226 PathAndCause {
227 path: val.0.to_string_lossy().to_string(),
228 cause: Cause::TomlSer(Box::new(val.1)),
229 }
230 }
231}
232
233impl std::error::Error for Error {}
238
239