| 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 | |