simple_fs/
error.rs

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	// -- Path
12	#[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	// -- File
23	#[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	// -- Remove
37	#[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	// -- Trash
43	#[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	// -- Sort
51	#[display("Cannot sort by globs.\nCause: {cause}")]
52	SortByGlobs {
53		cause: String,
54	},
55
56	// -- Metadata
57	#[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	// -- Time
63	#[display("Cannot get duration from system time. Cause: {_0}")]
64	CantGetDurationSystemTimeError(SystemTimeError),
65
66	// -- Directory
67	#[display("Cannot create directory (and parents) '{}'\nCause: {}", _0.path, _0.cause)]
68	DirCantCreateAll(PathAndCause),
69
70	// -- Path Validations
71	#[display("Path is invalid: '{}'\nCause: {}",_0.path, _0.cause)]
72	PathNotValidForPath(PathAndCause),
73
74	// -- Glob
75	#[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	// -- Watch
87	#[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	// -- Span
96	SpanInvalidStartAfterEnd,
97	SpanOutOfBounds,
98	SpanInvalidUtf8,
99
100	// -- Other
101	#[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	// -- with-json
110	#[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	// -- with-toml
121	#[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// region:    --- Cause Types
138
139#[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
163// endregion: --- Cause Types
164
165// region:    --- IO
166
167impl 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
185//std::time::SystemTimeError
186impl 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// endregion: --- IO
196
197// region:    --- JSON
198
199#[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// endregion: --- JSON
210
211// region:    --- TOML
212
213#[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
233// endregion: --- TOML
234
235// region:    --- Error Boilerplate
236
237impl std::error::Error for Error {}
238
239// endregion: --- Error Boilerplate