#[cfg(feature = "std")]
use std::process::ExitCode;
#[cfg(feature = "http")]
pub trait ProvidesHttpStatus {
fn http_status(&self) -> http::StatusCode;
}
#[cfg(feature = "std")]
pub trait ProvidesExitCode {
fn exit_code(&self) -> ExitCode;
}
#[cfg(all(feature = "app", feature = "std"))]
impl ProvidesExitCode for std::io::Error {
fn exit_code(&self) -> ExitCode {
use crate::app::consts::*;
use std::io::ErrorKind;
match self.kind() {
ErrorKind::NotFound => EX_NOINPUT,
ErrorKind::PermissionDenied => EX_NOPERM,
ErrorKind::NotADirectory | ErrorKind::IsADirectory => EX_USAGE,
ErrorKind::InvalidFilename => EX_DATAERR,
ErrorKind::StaleNetworkFileHandle => EX_IOERR,
ErrorKind::AlreadyExists
| ErrorKind::DirectoryNotEmpty
| ErrorKind::ReadOnlyFilesystem
| ErrorKind::StorageFull
| ErrorKind::QuotaExceeded
| ErrorKind::FileTooLarge
| ErrorKind::ExecutableFileBusy => EX_CANTCREAT,
ErrorKind::AddrInUse | ErrorKind::TooManyLinks | ErrorKind::ArgumentListTooLong => EX_OSERR,
ErrorKind::ResourceBusy
| ErrorKind::ConnectionReset
| ErrorKind::ConnectionAborted
| ErrorKind::TimedOut
| ErrorKind::WouldBlock
| ErrorKind::Interrupted => EX_TEMPFAIL,
ErrorKind::WriteZero | ErrorKind::BrokenPipe => EX_IOERR,
ErrorKind::ConnectionRefused | ErrorKind::NetworkDown => EX_UNAVAILABLE,
ErrorKind::HostUnreachable | ErrorKind::NetworkUnreachable | ErrorKind::AddrNotAvailable => EX_NOHOST,
ErrorKind::InvalidInput | ErrorKind::InvalidData | ErrorKind::UnexpectedEof => EX_DATAERR,
ErrorKind::NotConnected | ErrorKind::NotSeekable | ErrorKind::Deadlock | ErrorKind::CrossesDevices => {
EX_SOFTWARE
},
ErrorKind::Unsupported => EX_UNAVAILABLE,
ErrorKind::OutOfMemory => EX_OSERR,
_ => EX_IOERR,
}
.into()
}
}
#[cfg(all(feature = "http", feature = "std"))]
impl ProvidesHttpStatus for std::io::Error {
fn http_status(&self) -> http::StatusCode {
use http::StatusCode;
use std::io::ErrorKind;
match self.kind() {
ErrorKind::NotFound => StatusCode::NOT_FOUND,
ErrorKind::PermissionDenied => StatusCode::FORBIDDEN,
ErrorKind::AlreadyExists | ErrorKind::DirectoryNotEmpty => StatusCode::CONFLICT,
ErrorKind::NotADirectory
| ErrorKind::IsADirectory
| ErrorKind::InvalidFilename
| ErrorKind::InvalidInput => StatusCode::BAD_REQUEST,
ErrorKind::InvalidData | ErrorKind::UnexpectedEof => StatusCode::UNPROCESSABLE_ENTITY,
ErrorKind::FileTooLarge => StatusCode::PAYLOAD_TOO_LARGE,
ErrorKind::ReadOnlyFilesystem | ErrorKind::StorageFull | ErrorKind::QuotaExceeded => {
StatusCode::INSUFFICIENT_STORAGE
},
ErrorKind::Unsupported => StatusCode::NOT_IMPLEMENTED,
ErrorKind::ResourceBusy
| ErrorKind::ExecutableFileBusy
| ErrorKind::Interrupted
| ErrorKind::ConnectionRefused
| ErrorKind::ConnectionReset
| ErrorKind::ConnectionAborted
| ErrorKind::HostUnreachable
| ErrorKind::NetworkUnreachable
| ErrorKind::NetworkDown
| ErrorKind::AddrNotAvailable
| ErrorKind::TimedOut => StatusCode::SERVICE_UNAVAILABLE,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
#[cfg(test)]
#[path = "tests/providers.rs"]
mod tests;