1use thiserror::Error;
2
3#[derive(Error, Debug, PartialEq, Eq)]
5pub enum Error {
6 #[error("RequestDenied: {}", .0)]
8 RequestDenied(String),
9 #[error("Fatal: {}", .0)]
11 Fatal(String),
12 #[error("TryAgain")]
14 TryAgain,
15
16 #[error("SftpError: {}", .0)]
17 Sftp(crate::sftp::SftpError),
18}
19
20pub type SshResult<T> = Result<T, Error>;
22
23impl Error {
24 pub fn is_try_again(&self) -> bool {
25 matches!(self, Self::TryAgain)
26 }
27
28 pub fn fatal<S: Into<String>>(s: S) -> Self {
29 Self::Fatal(s.into())
30 }
31}
32
33impl From<std::io::Error> for Error {
34 fn from(err: std::io::Error) -> Error {
35 Error::fatal(err.to_string())
36 }
37}
38
39impl From<Error> for std::io::Error {
40 fn from(err: Error) -> std::io::Error {
41 match err {
42 Error::TryAgain => std::io::Error::new(std::io::ErrorKind::WouldBlock, "TryAgain"),
43 Error::RequestDenied(msg) | Error::Fatal(msg) => {
44 std::io::Error::new(std::io::ErrorKind::Other, msg)
45 }
46 Error::Sftp(err) => std::io::Error::new(std::io::ErrorKind::Other, err.to_string()),
47 }
48 }
49}
50
51impl From<std::ffi::NulError> for Error {
52 fn from(err: std::ffi::NulError) -> Error {
53 Error::Fatal(err.to_string())
54 }
55}