add_ed/io/local_io/
error.rs1use std::io::ErrorKind;
2
3#[derive(Debug)]
5pub enum LocalIOError {
6 NoPath,
8 #[allow(missing_docs)]
10 FilePermissionDenied{path: String},
11 #[allow(missing_docs)]
14 FileNotFound{path: String},
15 #[allow(missing_docs)]
18 FileIOFailed{path: String, error: std::io::Error},
19 ChildCreationFailed(std::io::Error),
21 ChildFailedToStart(std::io::Error),
23 ChildReturnedError(i32),
26 ChildKilledBySignal,
28 ChildPipingError,
30 BadUtf8(std::string::FromUtf8Error),
32}
33impl LocalIOError {
34 pub(super) fn file_error(path: &str, error: std::io::Error) -> Self {
35 let path = path.to_owned();
36 match error.kind() {
37 ErrorKind::PermissionDenied => Self::FilePermissionDenied{path},
38 ErrorKind::NotFound => Self::FileNotFound{path},
39 _ => Self::FileIOFailed{path, error},
40 }
41 }
42 pub(super) fn child_return_res(ret: Option<i32>) -> Self {
43 match ret {
44 Some(retval) => Self::ChildReturnedError(retval),
45 None => Self::ChildKilledBySignal,
46 }
47 }
48}
49
50impl std::error::Error for LocalIOError {}
51impl crate::error::IOErrorTrait for LocalIOError {}
52
53impl std::fmt::Display for LocalIOError {
54 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
55 match self {
56 Self::NoPath => { write!(f,
57 "Path must not be empty when performing file interactions."
58 )},
59 Self::FilePermissionDenied{path} => { write!(f,
60 "Permission denied, could not open file `{}`",
61 path,
62 )},
63 Self::FileNotFound{path} => { write!(f,
64 "Not found, could not open file `{}`",
65 path,
66 )},
67 Self::FileIOFailed{path, error} => { write!(f,
68 "Unknown error, could not open file `{}`.\nUnderlying error: {}",
69 path,
70 error,
71 )},
72 Self::ChildCreationFailed(e) => { write!(f,
73 "Failed to create shell process.\nUnderlying error: {}",
74 e,
75 )},
76 Self::ChildFailedToStart(e) => { write!(f,
77 "Failed to start shell process.\nUnderlying error: {}",
78 e,
79 )},
80 Self::ChildReturnedError(ret) => { write!(f,
81 "Shell process returned non-success result: {}\n{}",
82 ret,
83 "OBS! This is the result when a shell couldn't find a command."
84 )},
85 Self::ChildKilledBySignal => { write!(f,
86 "Shell process was killed by a signal.",
87 )},
88 Self::ChildPipingError => { write!(f,
89 "Error while piping data.",
90 )},
91 Self::BadUtf8(e) => { write!(f,
92 "Bad UTF-8 in read data.\nUnderlying error: {}",
93 e,
94 )},
95 }
96 }
97}
98
99impl std::cmp::PartialEq for LocalIOError {
100 fn eq(&self, other: &Self) -> bool {
101 use LocalIOError::*;
102 match (self, other) {
103 (FilePermissionDenied{path: a},FilePermissionDenied{path: b}) => a == b,
104 (FileNotFound{path: a},FileNotFound{path: b}) => a == b,
105 (ChildReturnedError(a),ChildReturnedError(b)) => a == b,
106 (ChildKilledBySignal,ChildKilledBySignal) => true,
107 (ChildPipingError,ChildPipingError) => true,
108 (BadUtf8(a),BadUtf8(b)) => a == b,
109 (FileIOFailed{path: a, error: b},FileIOFailed{path: c, error: d}) =>
111 a == c && b.kind() == d.kind()
112 ,
113 (ChildCreationFailed(a),ChildCreationFailed(b)) => a.kind() == b.kind(),
114 (ChildFailedToStart(a),ChildFailedToStart(b)) => a.kind() == b.kind(),
115 _ => false,
116 }
117 }
118}