starchart_backends/fs/
error.rs1use std::{
2 error::Error,
3 fmt::{Display, Formatter, Result as FmtResult},
4 io::Error as IoError,
5 path::PathBuf,
6};
7
8#[derive(Debug)]
13#[cfg(feature = "fs")]
14pub struct FsError {
15 pub(super) source: Option<Box<dyn Error + Send + Sync>>,
16 pub(super) kind: FsErrorType,
17}
18
19impl FsError {
20 #[must_use]
24 pub fn serde(err: Option<Box<dyn Error + Send + Sync>>) -> Self {
25 Self {
26 source: err,
27 kind: FsErrorType::Serde,
28 }
29 }
30
31 #[must_use = "retrieving the type has no effect if left unused"]
33 pub const fn kind(&self) -> &FsErrorType {
34 &self.kind
35 }
36
37 #[must_use = "consuming the error and retrieving the source has no effect if left unused"]
39 pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
40 self.source
41 }
42
43 #[must_use = "consuming the error into it's parts has no effect if left unused"]
45 pub fn into_parts(self) -> (FsErrorType, Option<Box<dyn Error + Send + Sync>>) {
46 (self.kind, self.source)
47 }
48}
49
50impl Display for FsError {
51 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
52 match &self.kind {
53 FsErrorType::Io => f.write_str("an IO error occurred"),
54 FsErrorType::PathNotDirectory(p) => {
55 f.write_str("path ")?;
56 Display::fmt(&p.display(), f)?;
57 f.write_str(" is not a directory")
58 }
59 FsErrorType::Serde => f.write_str("a (de)serialization error occurred"),
60 FsErrorType::InvalidFile(p) => {
61 f.write_str("file ")?;
62 Display::fmt(&p.display(), f)?;
63 f.write_str(" is invalid")
64 }
65 }
66 }
67}
68
69impl Error for FsError {
70 fn source(&self) -> Option<&(dyn Error + 'static)> {
71 self.source
72 .as_ref()
73 .map(|err| &**err as &(dyn Error + 'static))
74 }
75}
76
77impl From<IoError> for FsError {
78 fn from(e: IoError) -> Self {
79 Self {
80 source: Some(Box::new(e)),
81 kind: FsErrorType::Io,
82 }
83 }
84}
85
86impl From<FsError> for starchart::Error {
87 fn from(e: FsError) -> Self {
88 Self::backend(Some(Box::new(e)))
89 }
90}
91
92#[cfg(feature = "binary")]
93impl From<serde_bincode::Error> for FsError {
94 fn from(e: serde_bincode::Error) -> Self {
95 Self::serde(Some(e))
96 }
97}
98
99#[cfg(feature = "binary")]
100impl From<serde_bincode::ErrorKind> for FsError {
101 fn from(e: serde_bincode::ErrorKind) -> Self {
102 Self::serde(Some(Box::new(e)))
103 }
104}
105
106#[cfg(feature = "binary")]
107impl From<serde_cbor::Error> for FsError {
108 fn from(e: serde_cbor::Error) -> Self {
109 Self::serde(Some(Box::new(e)))
110 }
111}
112
113#[cfg(feature = "json")]
114impl From<serde_json::Error> for FsError {
115 fn from(e: serde_json::Error) -> Self {
116 Self::serde(Some(Box::new(e)))
117 }
118}
119
120#[cfg(feature = "toml")]
121impl From<serde_toml::de::Error> for FsError {
122 fn from(e: serde_toml::de::Error) -> Self {
123 Self::serde(Some(Box::new(e)))
124 }
125}
126
127#[cfg(feature = "toml")]
128impl From<serde_toml::ser::Error> for FsError {
129 fn from(e: serde_toml::ser::Error) -> Self {
130 Self::serde(Some(Box::new(e)))
131 }
132}
133
134#[cfg(feature = "yaml")]
135impl From<serde_yaml::Error> for FsError {
136 fn from(e: serde_yaml::Error) -> Self {
137 Self::serde(Some(Box::new(e)))
138 }
139}
140
141#[derive(Debug)]
143#[cfg(feature = "fs")]
144#[non_exhaustive]
145pub enum FsErrorType {
146 Io,
148 PathNotDirectory(PathBuf),
150 Serde,
152 InvalidFile(PathBuf),
154}