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	// -- Sort
43	#[display("Cannot sort by globs.\nCause: {cause}")]
44	SortByGlobs {
45		cause: String,
46	},
47
48	// -- Metadata
49	#[display("Cannot get metadata for path '{}'\nCause: {}", _0.path, _0.cause)]
50	CantGetMetadata(PathAndCause),
51	#[display("Cannot get 'modified' metadata for path '{}'\nCause: {}", _0.path, _0.cause)]
52	CantGetMetadataModified(PathAndCause),
53
54	// -- Time
55	#[display("Cannot get duration from system time. Cause: {_0}")]
56	CantGetDurationSystemTimeError(SystemTimeError),
57
58	// -- Directory
59	#[display("Cannot create directory (and parents) '{}'\nCause: {}", _0.path, _0.cause)]
60	DirCantCreateAll(PathAndCause),
61
62	// -- Path Validations
63	#[display("Path is invalid: '{}'\nCause: {}",_0.path, _0.cause)]
64	PathNotValidForPath(PathAndCause),
65
66	// -- Glob
67	#[display("Cannot create glob pattern '{glob}'.\nCause: {cause}")]
68	GlobCantNew {
69		glob: String,
70		cause: globset::Error,
71	},
72	#[display("Cannot build glob set from '{globs:?}'.\nCause: {cause}")]
73	GlobSetCantBuild {
74		globs: Vec<String>,
75		cause: globset::Error,
76	},
77
78	// -- Watch
79	#[display("Failed to watch path '{path}'.\nCause: {cause}")]
80	FailToWatch {
81		path: String,
82		cause: String,
83	},
84	#[display("Cannot watch path because it was not found: '{_0}'")]
85	CantWatchPathNotFound(String),
86
87	// -- Span
88	SpanInvalidStartAfterEnd,
89	SpanOutOfBounds,
90	SpanInvalidUtf8,
91
92	// -- Other
93	#[display("Cannot compute relative path from '{base}' to '{path}'")]
94	CannotDiff {
95		path: String,
96		base: String,
97	},
98	#[display("Cannot Canonicalize path '{}'\nCause: {}", _0.path, _0.cause)]
99	CannotCanonicalize(PathAndCause),
100
101	// -- with-json
102	#[cfg(feature = "with-json")]
103	#[display("Cannot read json path '{}'\nCause: {}", _0.path, _0.cause)]
104	JsonCantRead(PathAndCause),
105	#[cfg(feature = "with-json")]
106	#[display("Cannot write JSON to path '{}'\nCause: {}", _0.path, _0.cause)]
107	JsonCantWrite(PathAndCause),
108	#[cfg(feature = "with-json")]
109	#[display("Error processing NDJSON: {_0}")]
110	NdJson(String),
111
112	// -- with-toml
113	#[cfg(feature = "with-toml")]
114	#[display("Cannot read TOML from path '{}'\nCause: {}", _0.path, _0.cause)]
115	TomlCantRead(PathAndCause),
116	#[cfg(feature = "with-toml")]
117	#[display("Cannot write TOML to path '{}'\nCause: {}", _0.path, _0.cause)]
118	TomlCantWrite(PathAndCause),
119}
120
121impl Error {
122	pub fn sort_by_globs(cause: impl std::fmt::Display) -> Error {
123		Error::SortByGlobs {
124			cause: cause.to_string(),
125		}
126	}
127}
128
129// region:    --- Cause Types
130
131#[derive(Debug, Display, From)]
132pub enum Cause {
133	#[from]
134	Custom(String),
135
136	#[from]
137	Io(Box<io::Error>),
138
139	#[cfg(feature = "with-json")]
140	SerdeJson(Box<serde_json::Error>),
141
142	#[cfg(feature = "with-toml")]
143	TomlDe(Box<toml::de::Error>),
144
145	#[cfg(feature = "with-toml")]
146	TomlSer(Box<toml::ser::Error>),
147}
148
149#[derive(Debug)]
150pub struct PathAndCause {
151	pub path: String,
152	pub cause: Cause,
153}
154
155// endregion: --- Cause Types
156
157// region:    --- IO
158
159impl From<(&Path, io::Error)> for PathAndCause {
160	fn from(val: (&Path, io::Error)) -> Self {
161		PathAndCause {
162			path: val.0.to_string_lossy().to_string(),
163			cause: Cause::Io(Box::new(val.1)),
164		}
165	}
166}
167
168impl From<(&SPath, io::Error)> for PathAndCause {
169	fn from(val: (&SPath, io::Error)) -> Self {
170		PathAndCause {
171			path: val.0.to_string(),
172			cause: Cause::Io(Box::new(val.1)),
173		}
174	}
175}
176
177//std::time::SystemTimeError
178impl From<(&SPath, std::time::SystemTimeError)> for PathAndCause {
179	fn from(val: (&SPath, std::time::SystemTimeError)) -> Self {
180		PathAndCause {
181			path: val.0.to_string(),
182			cause: Cause::Custom(val.1.to_string()),
183		}
184	}
185}
186
187// endregion: --- IO
188
189// region:    --- JSON
190
191#[cfg(feature = "with-json")]
192impl From<(&Path, serde_json::Error)> for PathAndCause {
193	fn from(val: (&Path, serde_json::Error)) -> Self {
194		PathAndCause {
195			path: val.0.to_string_lossy().to_string(),
196			cause: Cause::SerdeJson(Box::new(val.1)),
197		}
198	}
199}
200
201// endregion: --- JSON
202
203// region:    --- TOML
204
205#[cfg(feature = "with-toml")]
206impl From<(&Path, toml::de::Error)> for PathAndCause {
207	fn from(val: (&Path, toml::de::Error)) -> Self {
208		PathAndCause {
209			path: val.0.to_string_lossy().to_string(),
210			cause: Cause::TomlDe(Box::new(val.1)),
211		}
212	}
213}
214
215#[cfg(feature = "with-toml")]
216impl From<(&Path, toml::ser::Error)> for PathAndCause {
217	fn from(val: (&Path, toml::ser::Error)) -> Self {
218		PathAndCause {
219			path: val.0.to_string_lossy().to_string(),
220			cause: Cause::TomlSer(Box::new(val.1)),
221		}
222	}
223}
224
225// endregion: --- TOML
226
227// region:    --- Error Boilerplate
228
229impl std::error::Error for Error {}
230
231// endregion: --- Error Boilerplate