use std::error::Error;
use std::fmt;
pub type MusshResult<T> = Result<T, MusshErr>;
#[derive(Debug)]
pub struct MusshErr {
inner: MusshErrKind,
}
impl Error for MusshErr {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.inner)
}
}
impl fmt::Display for MusshErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let err: &(dyn Error) = self;
write!(f, "{err}")?;
Ok(())
}
}
macro_rules! external_error {
($error:ty, $kind:expr) => {
impl From<$error> for MusshErr {
fn from(inner: $error) -> Self {
Self {
inner: $kind(inner),
}
}
}
};
}
impl From<MusshErrKind> for MusshErr {
fn from(inner: MusshErrKind) -> Self {
Self { inner }
}
}
impl From<&str> for MusshErr {
fn from(inner: &str) -> Self {
Self {
inner: MusshErrKind::Str(inner.to_string()),
}
}
}
external_error!(clap::Error, MusshErrKind::Clap);
external_error!(ssh2::Error, MusshErrKind::Ssh2);
external_error!(std::io::Error, MusshErrKind::Io);
external_error!(toml::de::Error, MusshErrKind::TomlDe);
external_error!(toml::ser::Error, MusshErrKind::TomlSer);
#[derive(Debug)]
pub(crate) enum MusshErrKind {
Clap(clap::Error),
Io(std::io::Error),
NonZero(String),
ShellNotFound,
Ssh2(ssh2::Error),
SshAuthentication,
SshExec(String),
SshSession,
Spawn,
Str(String),
TomlDe(toml::de::Error),
TomlSer(toml::ser::Error),
}
impl Error for MusshErrKind {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
MusshErrKind::Clap(inner) => inner.source(),
MusshErrKind::Io(inner) => inner.source(),
MusshErrKind::Ssh2(inner) => inner.source(),
MusshErrKind::TomlDe(inner) => inner.source(),
MusshErrKind::TomlSer(inner) => inner.source(),
_ => None,
}
}
}
impl fmt::Display for MusshErrKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MusshErrKind::Clap(inner) => write!(f, "{inner}"),
MusshErrKind::Io(inner) => write!(f, "{inner}"),
MusshErrKind::Ssh2(inner) => write!(f, "{inner}"),
MusshErrKind::TomlDe(inner) => write!(f, "{inner}"),
MusshErrKind::TomlSer(inner) => write!(f, "{inner}"),
MusshErrKind::NonZero(inner)
| MusshErrKind::SshExec(inner)
| MusshErrKind::Str(inner) => write!(f, "{inner}"),
_ => Ok(()),
}
}
}