use std::{
error, fmt,
fs::OpenOptions,
io::{self, Write},
path::Path,
};
pub use chrono::{DateTime, Local};
use colored::Colorize;
#[derive(Debug)]
pub enum Error {
Basic(DateTime<Local>, Box<dyn error::Error>),
Custom(DateTime<Local>, String),
}
impl Error {
pub fn time(&self) -> DateTime<Local> {
match self {
Self::Basic(time, _) => *time,
Self::Custom(time, _) => *time,
}
}
pub fn basic(err: impl error::Error + 'static) -> Error {
Error::Basic(Local::now(), Box::new(err))
}
pub fn custom<S>(msg: S) -> Error
where
S: ToString,
{
Error::Custom(Local::now(), msg.to_string())
}
pub fn report(&self) -> &Self {
eprintln!("\n{}:{}", "error".red().bold(), self);
self
}
pub fn panic(&self) {
panic!("{}", self);
}
pub fn log_to<P>(&self, path: P) -> &Self
where
P: AsRef<Path>,
{
match OpenOptions::new().create(true).append(true).open(path) {
Ok(mut file) => {
if let Err(err) = writeln!(file, "error:{}", self) {
Error::basic(err).report();
}
}
Err(err) => {
Error::basic(err).report();
}
}
self
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Basic(time, err) => write!(f, "\n\t time: {}\n\t msg: {}\n", time, err),
Self::Custom(time, msg) => write!(f, "\n\t time: {}\n\t msg: {}\n", time, msg),
}
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
Self::Basic(.., err) => Some(err.as_ref()),
Self::Custom(..) => None,
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self::basic(value)
}
}
impl From<fmt::Error> for Error {
fn from(value: fmt::Error) -> Self {
Self::basic(value)
}
}
impl From<&Self> for Error {
fn from(value: &Self) -> Self {
match value {
Error::Basic( time, err ) => Error::Basic(*time, Box::new(Error::custom(err.to_string()))),
Error::Custom(time, msg) => Error::Custom(*time, msg.to_string())
}
}
}
pub trait ErrResult<T> {
fn panic(self) -> T;
}
impl<T> ErrResult<T> for Result<T, Error> {
fn panic(self) -> T {
match self {
Ok(t) => t,
Err(err) => panic!("{}", err.to_string()),
}
}
}