fusabi_stdlib_ext/
error.rs1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Error, Debug)]
10pub enum Error {
11 #[error("operation not permitted: {0}")]
13 NotPermitted(String),
14
15 #[error("path not allowed: {0}")]
17 PathNotAllowed(String),
18
19 #[error("host not allowed: {0}")]
21 HostNotAllowed(String),
22
23 #[error("operation timed out after {0:?}")]
25 Timeout(std::time::Duration),
26
27 #[error("process error: {0}")]
29 Process(String),
30
31 #[error("process exited with code {code}: {message}")]
33 ProcessExit {
34 code: i32,
36 message: String,
38 },
39
40 #[error("filesystem error: {0}")]
42 Filesystem(String),
43
44 #[error("network error: {0}")]
46 Network(String),
47
48 #[error("format error: {0}")]
50 Format(String),
51
52 #[error("environment error: {0}")]
54 Environment(String),
55
56 #[error("module not available: {0}")]
58 ModuleNotAvailable(String),
59
60 #[error("invalid argument: {0}")]
62 InvalidArgument(String),
63
64 #[error("io error: {0}")]
66 Io(#[from] std::io::Error),
67
68 #[error("host error: {0}")]
70 Host(#[from] fusabi_host::Error),
71
72 #[error("internal error: {0}")]
74 Internal(String),
75
76 #[error("terminal UI error: {0}")]
78 TerminalUI(String),
79
80 #[error("kubernetes error: {0}")]
82 K8s(String),
83}
84
85impl Error {
86 pub fn not_permitted(msg: impl Into<String>) -> Self {
88 Self::NotPermitted(msg.into())
89 }
90
91 pub fn path_not_allowed(path: impl Into<String>) -> Self {
93 Self::PathNotAllowed(path.into())
94 }
95
96 pub fn host_not_allowed(host: impl Into<String>) -> Self {
98 Self::HostNotAllowed(host.into())
99 }
100
101 pub fn timeout(duration: std::time::Duration) -> Self {
103 Self::Timeout(duration)
104 }
105
106 pub fn process(msg: impl Into<String>) -> Self {
108 Self::Process(msg.into())
109 }
110
111 pub fn process_exit(code: i32, message: impl Into<String>) -> Self {
113 Self::ProcessExit {
114 code,
115 message: message.into(),
116 }
117 }
118
119 pub fn filesystem(msg: impl Into<String>) -> Self {
121 Self::Filesystem(msg.into())
122 }
123
124 pub fn network(msg: impl Into<String>) -> Self {
126 Self::Network(msg.into())
127 }
128
129 pub fn format(msg: impl Into<String>) -> Self {
131 Self::Format(msg.into())
132 }
133
134 pub fn invalid_argument(msg: impl Into<String>) -> Self {
136 Self::InvalidArgument(msg.into())
137 }
138
139 pub fn is_safety_error(&self) -> bool {
141 matches!(
142 self,
143 Self::NotPermitted(_) | Self::PathNotAllowed(_) | Self::HostNotAllowed(_)
144 )
145 }
146
147 pub fn is_timeout(&self) -> bool {
149 matches!(self, Self::Timeout(_))
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn test_error_display() {
159 let err = Error::path_not_allowed("/etc/passwd");
160 assert!(err.to_string().contains("/etc/passwd"));
161
162 let err = Error::process_exit(1, "command failed");
163 assert!(err.to_string().contains("code 1"));
164 }
165
166 #[test]
167 fn test_error_classification() {
168 assert!(Error::not_permitted("test").is_safety_error());
169 assert!(Error::path_not_allowed("/tmp").is_safety_error());
170 assert!(!Error::process("test").is_safety_error());
171
172 assert!(Error::timeout(std::time::Duration::from_secs(1)).is_timeout());
173 assert!(!Error::process("test").is_timeout());
174 }
175}