file_storage/error/
error.rs1use crate::StoragePath;
2use crate::{Operation, Reason};
3use std::fmt::{Display, Formatter};
4use std::io;
5use std::io::ErrorKind;
6use std::path::Path;
7
8#[derive(Debug)]
10pub struct Error {
11 path: StoragePath,
12 operation: Operation,
13 reason: Reason,
14 source: Option<io::Error>,
15}
16
17impl Error {
18 pub fn new<P>(path: P, operation: Operation, reason: Reason) -> Self
24 where
25 P: Into<StoragePath>,
26 {
27 let path: StoragePath = path.into();
28 Self {
29 path,
30 operation,
31 reason,
32 source: None,
33 }
34 }
35
36 pub fn from_source<P, E>(path: P, operation: Operation, source: E) -> Self
40 where
41 P: Into<StoragePath>,
42 E: Into<io::Error>,
43 {
44 let path: StoragePath = path.into();
45 Self {
46 path,
47 operation,
48 reason: Reason::Other,
49 source: Some(source.into()),
50 }
51 }
52
53 pub fn from_message<P, S>(path: P, operation: Operation, message: S) -> Self
58 where
59 P: Into<StoragePath>,
60 S: Into<String>,
61 {
62 Error::from_source(path, operation, io::Error::other(message.into()))
63 }
64}
65
66impl Error {
67 pub fn unknown_file_system(path: &str) -> io::Error {
71 io::Error::other(format!("unknown file system for path: {}", path))
72 }
73
74 pub fn path_not_utf8(path: &Path) -> io::Error {
76 io::Error::new(
77 ErrorKind::InvalidInput,
78 format!("path not utf-8: {:?}", path),
79 )
80 }
81}
82
83impl Error {
84 pub fn path(&self) -> &StoragePath {
88 &self.path
89 }
90
91 pub fn export_path(self) -> StoragePath {
93 self.path
94 }
95
96 pub fn operation(&self) -> Operation {
98 self.operation
99 }
100
101 pub fn reason(&self) -> Reason {
103 self.reason
104 }
105
106 pub fn source(&self) -> Option<&io::Error> {
108 self.source.as_ref()
109 }
110}
111
112impl From<Error> for io::Error {
113 fn from(error: Error) -> Self {
114 let kind: ErrorKind = match error.reason() {
115 Reason::UnknownFileSystem => ErrorKind::Unsupported,
116 Reason::UnsupportedOperation => ErrorKind::Unsupported,
117 Reason::FileNotFound => ErrorKind::NotFound,
118 Reason::FileAlreadyExists => ErrorKind::AlreadyExists,
119 Reason::FileContentNotUTF8 => ErrorKind::InvalidData,
120 Reason::Other => ErrorKind::Other,
121 };
122 Self::new(kind, error)
123 }
124}
125
126impl Display for Error {
127 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
128 let file_or_folder: &str = if self.path.is_file() {
129 "file"
130 } else {
131 "folder"
132 };
133 write!(
134 f,
135 "{} error: op={} path={} ",
136 file_or_folder, self.operation, self.path
137 )?;
138 if let Some(source) = self.source() {
139 write!(f, "source={}", source)?;
140 } else {
141 write!(f, "reason={}", self.reason)?;
142 }
143 Ok(())
144 }
145}
146
147impl std::error::Error for Error {}