use core::fmt;
use std::{error::Error, io};
pub type CustomUserError = Box<dyn Error + Send + Sync + 'static>;
#[derive(Debug)]
pub enum InquireError {
NotTTY,
InvalidConfiguration(String),
IO(io::Error),
OperationCanceled,
OperationInterrupted,
Custom(CustomUserError),
}
impl Error for InquireError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
InquireError::IO(err) => Some(err),
InquireError::Custom(err) => Some(err.as_dyn_error()),
_ => None,
}
}
}
trait AsDynError<'a> {
fn as_dyn_error(&self) -> &(dyn Error + 'a);
}
impl<'a> AsDynError<'a> for dyn Error + Send + Sync + 'a {
#[inline]
fn as_dyn_error(&self) -> &(dyn Error + 'a) {
self
}
}
impl From<CustomUserError> for InquireError {
fn from(err: CustomUserError) -> Self {
InquireError::Custom(err)
}
}
impl From<io::Error> for InquireError {
fn from(err: io::Error) -> Self {
match err.raw_os_error() {
Some(25 | 6) => InquireError::NotTTY,
_ => InquireError::IO(err),
}
}
}
impl fmt::Display for InquireError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
InquireError::NotTTY => f.write_str("The input device is not a TTY"),
InquireError::InvalidConfiguration(s) => {
write!(f, "The prompt configuration is invalid: {}", s)
}
InquireError::IO(err) => write!(f, "IO error: {}", err),
InquireError::OperationCanceled => f.write_str("Operation was canceled by the user"),
InquireError::OperationInterrupted => {
f.write_str("Operation was interrupted by the user")
}
InquireError::Custom(err) => write!(f, "User-provided error: {}", err),
}
}
}
pub type InquireResult<T> = Result<T, InquireError>;