use crate::disentangle;
use bitflags::parser::ParseError as BitFlagsParseError;
use cargo_toml::Error as CargoTomlError;
use clap::error::Error as ClapError;
use reedline::ReedlineError;
use serde_merge::error::Error as SerdeMergeError;
use std::borrow::Cow;
use std::string::FromUtf8Error;
use std::sync::{MutexGuard, PoisonError as LockError};
use std::{error::Error, io};
use strum::ParseError as StrumParseError;
use syn::Error as SynError;
use toml::de::Error as TomlDeError;
use toml::ser::Error as TomlSerError;
pub type ThagResult<T> = Result<T, ThagError>;
#[derive(Debug)]
pub enum ThagError {
BitFlagsParse(BitFlagsParseError), Cancelled, ClapError(ClapError), Command(&'static str), Dyn(Box<dyn Error>), FromStr(Cow<'static, str>), FromUtf8(FromUtf8Error), Io(std::io::Error), LockMutexGuard(&'static str), Logic(&'static str), NoneOption(&'static str), OsString(std::ffi::OsString), Reedline(ReedlineError), SerdeMerge(SerdeMergeError), StrumParse(StrumParseError), Syn(SynError), TomlDe(TomlDeError), TomlSer(TomlSerError), Toml(CargoTomlError), UnsupportedTerm, Validation(String), }
impl From<FromUtf8Error> for ThagError {
fn from(err: FromUtf8Error) -> Self {
Self::FromUtf8(err)
}
}
impl From<io::Error> for ThagError {
fn from(err: io::Error) -> Self {
Self::Io(err)
}
}
impl From<ClapError> for ThagError {
fn from(err: ClapError) -> Self {
Self::ClapError(err)
}
}
impl From<StrumParseError> for ThagError {
fn from(err: StrumParseError) -> Self {
Self::StrumParse(err)
}
}
impl From<TomlDeError> for ThagError {
fn from(err: TomlDeError) -> Self {
Self::TomlDe(err)
}
}
impl From<TomlSerError> for ThagError {
fn from(err: TomlSerError) -> Self {
Self::TomlSer(err)
}
}
impl From<CargoTomlError> for ThagError {
fn from(err: CargoTomlError) -> Self {
Self::Toml(err)
}
}
impl From<String> for ThagError {
fn from(s: String) -> Self {
Self::FromStr(Cow::Owned(s))
}
}
impl From<&'static str> for ThagError {
fn from(s: &'static str) -> Self {
Self::FromStr(Cow::Borrowed(s))
}
}
impl From<ReedlineError> for ThagError {
fn from(err: ReedlineError) -> Self {
Self::Reedline(err)
}
}
impl From<SerdeMergeError> for ThagError {
fn from(err: SerdeMergeError) -> Self {
Self::SerdeMerge(err)
}
}
impl From<SynError> for ThagError {
fn from(err: SynError) -> Self {
Self::Syn(err)
}
}
impl<'a, T> From<LockError<MutexGuard<'a, T>>> for ThagError {
fn from(_err: LockError<MutexGuard<'a, T>>) -> Self {
Self::LockMutexGuard("Lock poisoned")
}
}
impl From<BitFlagsParseError> for ThagError {
fn from(err: BitFlagsParseError) -> Self {
Self::BitFlagsParse(err)
}
}
impl From<Box<dyn Error>> for ThagError {
fn from(err: Box<dyn Error>) -> Self {
Self::Dyn(err)
}
}
impl std::fmt::Display for ThagError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BitFlagsParse(e) => write!(f, "{e}"),
Self::Cancelled => write!(f, "Cancelled"),
Self::ClapError(e) => write!(f, "{e}"),
Self::Command(s) | Self::Logic(s) | Self::NoneOption(s) => {
for line in s.lines() {
writeln!(f, "{line}")?;
}
Ok(())
}
Self::Dyn(e) => write!(f, "{e}"),
Self::FromStr(s) => {
for line in s.lines() {
writeln!(f, "{line}")?;
}
Ok(())
}
Self::FromUtf8(e) => write!(f, "{e}"),
Self::Io(e) => write!(f, "{e}"),
Self::LockMutexGuard(e) => write!(f, "{e}"),
Self::OsString(o) => writeln!(f, "<invalid UTF-8: {o:?}>"),
Self::Reedline(e) => write!(f, "{e}"),
Self::SerdeMerge(e) => write!(f, "{e}"),
Self::StrumParse(e) => write!(f, "{e}"),
Self::Syn(e) => write!(f, "{e}"),
Self::TomlDe(e) => write!(f, "{e}"),
Self::TomlSer(e) => write!(f, "{e}"),
Self::Toml(e) => {
let msg = e.to_string();
write!(f, "TOML error: {}", disentangle(msg.as_str()))?;
Ok(())
}
Self::UnsupportedTerm => write!(f, "Unsupported terminal type"),
Self::Validation(e) => write!(f, "{e}"),
}
}
}
impl Error for ThagError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::BitFlagsParse(e) => Some(e),
Self::Cancelled | Self::UnsupportedTerm => Some(self),
Self::ClapError(ref e) => Some(e),
Self::Command(_e) => Some(self),
Self::Dyn(e) => Some(&**e),
Self::FromStr(ref _e) => Some(self),
Self::FromUtf8(e) => Some(e),
Self::Io(ref e) => Some(e),
Self::LockMutexGuard(_e) => Some(self),
Self::Logic(_e) => Some(self),
Self::NoneOption(_e) => Some(self),
Self::OsString(ref _o) => Some(self),
Self::Reedline(e) => Some(e),
Self::SerdeMerge(ref e) => Some(e),
Self::StrumParse(ref e) => Some(e),
Self::Syn(e) => Some(e),
Self::TomlDe(ref e) => Some(e),
Self::TomlSer(ref e) => Some(e),
Self::Toml(ref e) => Some(e),
Self::Validation(ref _e) => Some(self),
}
}
}