1 | use std::error::Error as StdError; |
2 | use std::ffi::OsString; |
3 | use std::fmt; |
4 | use std::io::Error as IoError; |
5 | use std::io::ErrorKind as IoErrorKind; |
6 | use std::path::StripPrefixError; |
7 | |
8 | /// A list specifying general categories of fs_extra error. |
9 | #[derive (Debug)] |
10 | pub enum ErrorKind { |
11 | /// An entity was not found. |
12 | NotFound, |
13 | /// The operation lacked the necessary privileges to complete. |
14 | PermissionDenied, |
15 | /// An entity already exists. |
16 | AlreadyExists, |
17 | /// This operation was interrupted. |
18 | Interrupted, |
19 | /// Path does not a directory. |
20 | InvalidFolder, |
21 | /// Path does not a file. |
22 | InvalidFile, |
23 | /// Invalid file name. |
24 | InvalidFileName, |
25 | /// Invalid path. |
26 | InvalidPath, |
27 | /// Any I/O error. |
28 | Io(IoError), |
29 | /// Any StripPrefix error. |
30 | StripPrefix(StripPrefixError), |
31 | /// Any OsString error. |
32 | OsString(OsString), |
33 | /// Any fs_extra error not part of this list. |
34 | Other, |
35 | } |
36 | |
37 | impl ErrorKind { |
38 | fn as_str(&self) -> &str { |
39 | match *self { |
40 | ErrorKind::NotFound => "entity not found" , |
41 | ErrorKind::PermissionDenied => "permission denied" , |
42 | ErrorKind::AlreadyExists => "entity already exists" , |
43 | ErrorKind::Interrupted => "operation interrupted" , |
44 | ErrorKind::Other => "other os error" , |
45 | ErrorKind::InvalidFolder => "invalid folder error" , |
46 | ErrorKind::InvalidFile => "invalid file error" , |
47 | ErrorKind::InvalidFileName => "invalid file name error" , |
48 | ErrorKind::InvalidPath => "invalid path error" , |
49 | ErrorKind::Io(_) => "Io error" , |
50 | ErrorKind::StripPrefix(_) => "Strip prefix error" , |
51 | ErrorKind::OsString(_) => "OsString error" , |
52 | } |
53 | } |
54 | } |
55 | |
56 | /// A specialized Result type for fs_extra operations. |
57 | /// |
58 | /// This typedef is generally used to avoid writing out fs_extra::Error directly |
59 | /// and is otherwise a direct mapping to Result. |
60 | /// |
61 | ///#Examples |
62 | /// |
63 | /// ```rust,ignore |
64 | /// extern crate fs_extra; |
65 | /// use fs_extra::dir::create; |
66 | /// |
67 | ///fn get_string() -> io::Result<()> { |
68 | /// |
69 | /// create("test_dir" )?; |
70 | /// |
71 | /// Ok(()) |
72 | /// } |
73 | /// ``` |
74 | pub type Result<T> = ::std::result::Result<T, Error>; |
75 | |
76 | /// The error type for fs_extra operations with files and folder. |
77 | /// |
78 | /// Errors mostly originate from the underlying OS, but custom instances of |
79 | /// `Error` can be created with crafted error messages and a particular value of |
80 | /// [`ErrorKind`]. |
81 | /// |
82 | /// [`ErrorKind`]: enum.ErrorKind.html |
83 | #[derive (Debug)] |
84 | pub struct Error { |
85 | /// Type error |
86 | pub kind: ErrorKind, |
87 | message: String, |
88 | } |
89 | |
90 | impl Error { |
91 | /// Create a new fs_extra error from a kind of error error as well as an arbitrary error payload. |
92 | /// |
93 | ///#Examples |
94 | /// ```rust,ignore |
95 | /// |
96 | /// extern crate fs_extra; |
97 | /// use fs_extra::error::{Error, ErrorKind}; |
98 | /// |
99 | /// errors can be created from strings |
100 | /// let custom_error = Error::new(ErrorKind::Other, "Other Error!" ); |
101 | /// // errors can also be created from other errors |
102 | /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error); |
103 | /// |
104 | /// ``` |
105 | pub fn new(kind: ErrorKind, message: &str) -> Error { |
106 | Error { |
107 | kind, |
108 | message: message.to_string(), |
109 | } |
110 | } |
111 | } |
112 | |
113 | impl fmt::Display for Error { |
114 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
115 | write!(f, " {}" , self.message) |
116 | } |
117 | } |
118 | |
119 | impl StdError for Error { |
120 | fn description(&self) -> &str { |
121 | self.kind.as_str() |
122 | } |
123 | } |
124 | impl From<StripPrefixError> for Error { |
125 | fn from(err: StripPrefixError) -> Error { |
126 | Error::new( |
127 | kind:ErrorKind::StripPrefix(err), |
128 | message:"StripPrefixError. Look inside for more details" , |
129 | ) |
130 | } |
131 | } |
132 | |
133 | impl From<OsString> for Error { |
134 | fn from(err: OsString) -> Error { |
135 | Error::new( |
136 | kind:ErrorKind::OsString(err), |
137 | message:"OsString. Look inside for more details" , |
138 | ) |
139 | } |
140 | } |
141 | |
142 | impl From<IoError> for Error { |
143 | fn from(err: IoError) -> Error { |
144 | let err_kind: ErrorKind; |
145 | match err.kind() { |
146 | IoErrorKind::NotFound => err_kind = ErrorKind::NotFound, |
147 | IoErrorKind::PermissionDenied => err_kind = ErrorKind::PermissionDenied, |
148 | IoErrorKind::AlreadyExists => err_kind = ErrorKind::AlreadyExists, |
149 | IoErrorKind::Interrupted => err_kind = ErrorKind::Interrupted, |
150 | IoErrorKind::Other => err_kind = ErrorKind::Other, |
151 | _ => { |
152 | err_kind = ErrorKind::Io(err); |
153 | return Error::new(err_kind, message:"Io error. Look inside err_kind for more details." ); |
154 | } |
155 | } |
156 | Error::new(err_kind, &err.to_string()) |
157 | } |
158 | } |
159 | |