use std::fmt;
#[derive(Debug)]
pub enum PromptError {
Interrupted,
Io(std::io::Error),
}
impl fmt::Display for PromptError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Interrupted => write!(f, "prompt interrupted by user"),
Self::Io(e) => write!(f, "prompt I/O error: {e}"),
}
}
}
impl std::error::Error for PromptError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Io(e) => Some(e),
_ => None,
}
}
}
impl From<std::io::Error> for PromptError {
fn from(e: std::io::Error) -> Self {
Self::Io(e)
}
}
pub type Result<T> = std::result::Result<T, PromptError>;
pub fn is_cancel(err: &PromptError) -> bool {
matches!(err, PromptError::Interrupted)
}
pub trait OnCancel<T> {
fn or_cancel(self, message: &str) -> T;
fn or_cancel_default(self) -> T;
}
impl<T> OnCancel<T> for Result<T> {
fn or_cancel(self, message: &str) -> T {
match self {
Ok(v) => v,
Err(PromptError::Interrupted) => {
super::cancel(message);
std::process::exit(0);
}
Err(e) => panic!("{e}"),
}
}
fn or_cancel_default(self) -> T {
let msg = super::settings::get().cancel;
self.or_cancel(&msg)
}
}