use std::{
fmt,
process::exit,
};
use colored::*;
pub enum Error<T: fmt::Display> {
UnrecognizedSubcommand (T),
UnrecognizedFlag (T),
UnrecognizedArgument (T),
CouldNotFindFile (T),
CouldNotReadFile (T),
NoInputFile,
CouldNotParseNumber (T),
CouldNotParse (T),
UnexpectedEOF (T),
Expected (T, T),
CouldNotParseExponent (T),
NoHelpAvailable (T),
CouldNotReadLine (T),
CouldNotFlushStdout (T),
UndeclaredVariable (T),
UnmatchedUnits (T, T, T),
}
impl<T: fmt::Display> fmt::Display for Error<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use Error::*;
let string = match self {
UnrecognizedSubcommand (s) => format!("Did not recognize subcommand: {}", s),
UnrecognizedFlag (s) => format!("Did not recognize flag: {}", s),
UnrecognizedArgument (s) => format!("Did not recognize argument: {}", s),
CouldNotFindFile (s) => format!("Could not locate file: {}", s),
CouldNotReadFile (s) => format!("Could not read file: {}", s),
NoInputFile => format!("No input file provided"),
CouldNotParseNumber (s) => format!("Could not parse number: {}", s),
CouldNotParse (s) => format!("Could not parse near token ({})", s),
UnexpectedEOF (s) => format!("Unexpected EOF near token ({})", s),
Expected (x, a) => format!("Expected token of class ({}) but instead found token of class ({})", x, a),
CouldNotParseExponent (s) => format!("Could not parse as numeric exponent: {}", s),
NoHelpAvailable (s) => format!("No help available for subcommand: {}", s),
CouldNotReadLine (i) => format!("Could not read user input near In[{}]", i),
CouldNotFlushStdout (i) => format!("Could not flust stdout near In[{}]", i),
UndeclaredVariable (s) => format!("Found undeclared variable: {}", s),
UnmatchedUnits (u, l, r) => format!("Unmatched unit powers ({}^{}) and ({}^{})", u, l, u, r),
};
write!(f, "{}", string)
}
}
impl<T: fmt::Display> Error<T> {
pub fn throw(&self) -> ! {
println!("{} {}", "(error)".truecolor(255, 60, 40).bold(), self);
exit(0);
}
pub fn warn(&self) {
println!("{} {}\n", "(warn)".truecolor(252, 115, 3).bold(), self);
}
}