use std::io;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
Io(io::Error),
Json(serde_json::Error),
Prompt(crate::prompt::PromptError),
Tmux(String),
MissingDep(&'static str),
SubprocessTimeout {
what: String,
ceiling_s: u64,
},
SubprocessFailed {
what: String,
code: i32,
},
Invalid(String),
Message(String),
}
impl Error {
pub fn msg(s: impl Into<String>) -> Self {
Self::Message(s.into())
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Io(e) => write!(f, "I/O: {e}"),
Self::Json(e) => write!(f, "JSON: {e}"),
Self::Prompt(e) => write!(f, "prompt: {e}"),
Self::Tmux(s) => write!(f, "tmux: {s}"),
Self::MissingDep(s) => write!(f, "missing dep on PATH: {s}"),
Self::SubprocessTimeout { what, ceiling_s } => {
write!(f, "subprocess `{what}` timed out after {ceiling_s}s")
}
Self::SubprocessFailed { what, code } => {
write!(f, "subprocess `{what}` failed (exit {code})")
}
Self::Invalid(s) => write!(f, "invalid input: {s}"),
Self::Message(s) => f.write_str(s),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Io(e) => Some(e),
Self::Json(e) => Some(e),
Self::Prompt(e) => Some(e),
_ => None,
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Self::Io(e)
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Self::Json(e)
}
}
impl From<crate::prompt::PromptError> for Error {
fn from(e: crate::prompt::PromptError) -> Self {
Self::Prompt(e)
}
}
impl From<netsky_sh::Error> for Error {
fn from(e: netsky_sh::Error) -> Self {
Self::Tmux(format!("{e}"))
}
}
impl From<std::time::SystemTimeError> for Error {
fn from(e: std::time::SystemTimeError) -> Self {
Self::Message(format!("system time: {e}"))
}
}
impl From<std::num::ParseIntError> for Error {
fn from(e: std::num::ParseIntError) -> Self {
Self::Invalid(format!("parse int: {e}"))
}
}
#[macro_export]
macro_rules! bail {
($fmt:literal $(,)?) => {
return Err($crate::error::Error::Message(format!($fmt)))
};
($fmt:expr, $($arg:tt)*) => {
return Err($crate::error::Error::Message(format!($fmt, $($arg)*)))
};
}
#[macro_export]
macro_rules! anyhow {
($fmt:literal $(,)?) => {
$crate::error::Error::Message(format!($fmt))
};
($fmt:expr, $($arg:tt)*) => {
$crate::error::Error::Message(format!($fmt, $($arg)*))
};
}