#[derive(Debug, PartialEq)]
#[allow(non_camel_case_types)] pub enum ErrorKind {
SHELL_NOT_FOUND,
COMMAND_FAILED,
NO_LAUNCHER,
IO,
}
pub struct Error {
kind: ErrorKind, message: String, }
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind
}
}
impl Eq for Error {}
impl Error {
pub fn new<T: AsRef<str>>(kind: ErrorKind, message: T) -> Self {
let message: &str = message.as_ref();
if message.is_empty() {
Self::empty_message(kind)
} else {
Self {
kind,
message: message.to_string(),
}
}
}
fn empty_message(kind: ErrorKind) -> Self {
Self {
kind,
message: "".to_string(),
}
}
pub const fn kind(&self) -> &ErrorKind {
&self.kind
}
pub fn message(&self) -> &str {
self.message.as_str()
}
}
impl core::fmt::Display for ErrorKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
ErrorKind::SHELL_NOT_FOUND => {
write!(f, "Unrecognized shell type")
}
ErrorKind::COMMAND_FAILED => {
write!(f, "Command failed")
}
ErrorKind::NO_LAUNCHER => {
write!(f, "No launcher worked")
}
ErrorKind::IO => {
write!(f, "IO Error")
}
}
}
}
impl core::fmt::Debug for Error {
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut debug = fmt.debug_struct("Error");
debug
.field("kind", &self.kind())
.field("message", &self.message())
.finish()
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if self.message().is_empty() {
write!(f, "{}", self.kind)
} else {
write!(f, "{} ({})", self.kind, self.message)
}
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::new(ErrorKind::IO, err.to_string().as_str())
}
}
impl std::error::Error for Error {}
pub type Result<T> = core::result::Result<T, Error>;