use crossterm::ErrorKind as CrosstermError;
use std::{
error::Error as ErrorTrait,
fmt,
num::ParseIntError,
string::FromUtf8Error,
};
use tokio::{io, task::JoinError};
#[derive(Debug, Clone)]
pub struct AlreadyRunning;
impl fmt::Display for AlreadyRunning {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.pad("there already is an instance of terminal services running")
}
}
impl ErrorTrait for AlreadyRunning {}
#[derive(Debug, Clone)]
pub struct ServicesOff;
impl fmt::Display for ServicesOff {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.pad("terminal event listener and/or screen render disconnected")
}
}
impl ErrorTrait for ServicesOff {}
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKind {
AlreadyRunning(AlreadyRunning),
ServicesOff(ServicesOff),
IO(io::Error),
Fmt(fmt::Error),
ParseInt(ParseIntError),
Utf8(FromUtf8Error),
Join(JoinError),
Custom(Box<dyn ErrorTrait + Send + Sync>),
}
impl ErrorKind {
pub fn as_dyn(&self) -> &(dyn ErrorTrait + 'static + Send + Sync) {
match self {
ErrorKind::AlreadyRunning(error) => error,
ErrorKind::ServicesOff(error) => error,
ErrorKind::IO(error) => error,
ErrorKind::Fmt(error) => error,
ErrorKind::ParseInt(error) => error,
ErrorKind::Utf8(error) => error,
ErrorKind::Join(error) => error,
ErrorKind::Custom(error) => &**error,
}
}
pub(crate) fn from_crossterm(error: CrosstermError) -> Self {
match error {
CrosstermError::IoError(error) => ErrorKind::IO(error),
CrosstermError::FmtError(error) => ErrorKind::Fmt(error),
CrosstermError::Utf8Error(error) => ErrorKind::Utf8(error),
CrosstermError::ParseIntError(error) => ErrorKind::ParseInt(error),
error => ErrorKind::Custom(Box::new(error)),
}
}
}
impl From<AlreadyRunning> for ErrorKind {
fn from(error: AlreadyRunning) -> Self {
ErrorKind::AlreadyRunning(error)
}
}
impl From<ServicesOff> for ErrorKind {
fn from(error: ServicesOff) -> Self {
ErrorKind::ServicesOff(error)
}
}
impl From<io::Error> for ErrorKind {
fn from(error: io::Error) -> Self {
ErrorKind::IO(error)
}
}
impl From<ParseIntError> for ErrorKind {
fn from(error: ParseIntError) -> Self {
ErrorKind::ParseInt(error)
}
}
impl From<FromUtf8Error> for ErrorKind {
fn from(error: FromUtf8Error) -> Self {
ErrorKind::Utf8(error)
}
}
impl From<fmt::Error> for ErrorKind {
fn from(error: fmt::Error) -> Self {
ErrorKind::Fmt(error)
}
}
impl From<JoinError> for ErrorKind {
fn from(error: JoinError) -> Self {
ErrorKind::Join(error)
}
}
impl From<Box<dyn ErrorTrait + Send + Sync>> for ErrorKind {
fn from(error: Box<dyn ErrorTrait + Send + Sync>) -> Self {
ErrorKind::Custom(error)
}
}
#[derive(Debug)]
pub struct Error {
kind: Box<ErrorKind>,
}
impl Error {
pub fn new(kind: ErrorKind) -> Self {
Self { kind: Box::new(kind) }
}
pub fn as_dyn(&self) -> &(dyn ErrorTrait + 'static + Send + Sync) {
self.kind.as_dyn()
}
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
pub(crate) fn from_crossterm(error: CrosstermError) -> Self {
Self::new(ErrorKind::from_crossterm(error))
}
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}", self.as_dyn())
}
}
impl ErrorTrait for Error {
fn source(&self) -> Option<&(dyn ErrorTrait + 'static)> {
Some(self.as_dyn())
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Self {
Self::new(kind)
}
}
impl From<AlreadyRunning> for Error {
fn from(error: AlreadyRunning) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<ServicesOff> for Error {
fn from(error: ServicesOff) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<ParseIntError> for Error {
fn from(error: ParseIntError) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<FromUtf8Error> for Error {
fn from(error: FromUtf8Error) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<fmt::Error> for Error {
fn from(error: fmt::Error) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<JoinError> for Error {
fn from(error: JoinError) -> Self {
Self::new(ErrorKind::from(error))
}
}
impl From<Box<dyn ErrorTrait + Send + Sync>> for Error {
fn from(error: Box<dyn ErrorTrait + Send + Sync>) -> Self {
Self::new(ErrorKind::from(error))
}
}