mirror of https://github.com/chipsenkbeil/distant
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.2 KiB
Rust
149 lines
4.2 KiB
Rust
use distant_core::{RemoteProcessError, SessionChannelExtError, TransportError, WatchError};
|
|
|
|
/// Exit codes following https://www.freebsd.org/cgi/man.cgi?query=sysexits&sektion=3
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
|
pub enum ExitCode {
|
|
/// EX_USAGE (64) - being used when arguments missing or bad arguments provided to CLI
|
|
Usage,
|
|
|
|
/// EX_DATAERR (65) - being used when bad data received not in UTF-8 format or transport data
|
|
/// is bad
|
|
DataErr,
|
|
|
|
/// EX_NOINPUT (66) - being used when not getting expected data from launch
|
|
NoInput,
|
|
|
|
/// EX_NOHOST (68) - being used when failed to resolve a host
|
|
NoHost,
|
|
|
|
/// EX_UNAVAILABLE (69) - being used when IO error encountered where connection is problem
|
|
Unavailable,
|
|
|
|
/// EX_SOFTWARE (70) - being used for when an action fails as well as for internal errors that
|
|
/// can occur like joining a task
|
|
Software,
|
|
|
|
/// EX_OSERR (71) - being used when fork failed
|
|
OsErr,
|
|
|
|
/// EX_IOERR (74) - being used as catchall for IO errors
|
|
IoError,
|
|
|
|
/// EX_TEMPFAIL (75) - being used when we get a timeout
|
|
TempFail,
|
|
|
|
/// EX_PROTOCOL (76) - being used as catchall for transport errors
|
|
Protocol,
|
|
|
|
/// Custom exit code to pass back verbatim
|
|
Custom(i32),
|
|
}
|
|
|
|
impl ExitCode {
|
|
/// Convert into numeric exit code
|
|
pub fn to_i32(self) -> i32 {
|
|
match self {
|
|
Self::Usage => 64,
|
|
Self::DataErr => 65,
|
|
Self::NoInput => 66,
|
|
Self::NoHost => 68,
|
|
Self::Unavailable => 69,
|
|
Self::Software => 70,
|
|
Self::OsErr => 71,
|
|
Self::IoError => 74,
|
|
Self::TempFail => 75,
|
|
Self::Protocol => 76,
|
|
Self::Custom(x) => x,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<ExitCode> for i32 {
|
|
fn from(code: ExitCode) -> Self {
|
|
code.to_i32()
|
|
}
|
|
}
|
|
|
|
/// Represents an error that can be converted into an exit code
|
|
pub trait ExitCodeError: std::error::Error {
|
|
fn to_exit_code(&self) -> ExitCode;
|
|
|
|
/// Indicates if the error message associated with this exit code error
|
|
/// should be printed, or if this is just used to reflect the exit code
|
|
/// when the process exits
|
|
fn is_silent(&self) -> bool {
|
|
false
|
|
}
|
|
|
|
fn to_i32(&self) -> i32 {
|
|
self.to_exit_code().to_i32()
|
|
}
|
|
}
|
|
|
|
impl ExitCodeError for std::io::Error {
|
|
fn to_exit_code(&self) -> ExitCode {
|
|
use std::io::ErrorKind;
|
|
match self.kind() {
|
|
ErrorKind::ConnectionAborted
|
|
| ErrorKind::ConnectionRefused
|
|
| ErrorKind::ConnectionReset
|
|
| ErrorKind::NotConnected => ExitCode::Unavailable,
|
|
ErrorKind::InvalidData => ExitCode::DataErr,
|
|
ErrorKind::TimedOut => ExitCode::TempFail,
|
|
_ => ExitCode::IoError,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ExitCodeError for TransportError {
|
|
fn to_exit_code(&self) -> ExitCode {
|
|
match self {
|
|
TransportError::IoError(x) => x.to_exit_code(),
|
|
_ => ExitCode::Protocol,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ExitCodeError for RemoteProcessError {
|
|
fn is_silent(&self) -> bool {
|
|
true
|
|
}
|
|
|
|
fn to_exit_code(&self) -> ExitCode {
|
|
match self {
|
|
Self::ChannelDead => ExitCode::Unavailable,
|
|
Self::TransportError(x) => x.to_exit_code(),
|
|
Self::UnexpectedEof => ExitCode::IoError,
|
|
Self::WaitFailed(_) => ExitCode::Software,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ExitCodeError for SessionChannelExtError {
|
|
fn to_exit_code(&self) -> ExitCode {
|
|
match self {
|
|
Self::Failure(_) => ExitCode::Software,
|
|
Self::TransportError(x) => x.to_exit_code(),
|
|
Self::MismatchedResponse => ExitCode::Protocol,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ExitCodeError for WatchError {
|
|
fn to_exit_code(&self) -> ExitCode {
|
|
match self {
|
|
Self::MissingConfirmation => ExitCode::Protocol,
|
|
Self::ServerError(_) => ExitCode::Software,
|
|
Self::TransportError(x) => x.to_exit_code(),
|
|
Self::QueuedChangeDropped => ExitCode::Software,
|
|
Self::UnexpectedResponse(_) => ExitCode::Protocol,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: ExitCodeError + 'static> From<T> for Box<dyn ExitCodeError> {
|
|
fn from(x: T) -> Self {
|
|
Box::new(x)
|
|
}
|
|
}
|