heck_string_cli/
errors.rs

1use std::fmt::Display;
2
3#[derive(Debug, Clone)]
4pub enum Error {
5    IOError(String),
6    RuntimeError(String),
7    HeckError(String),
8}
9impl Display for Error {
10    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
11        write!(
12            f,
13            "{}: {}",
14            self.variant(),
15            match self {
16                Error::IOError(e) => e.to_string(),
17                Error::RuntimeError(e) => e.to_string(),
18                Error::HeckError(e) => e.to_string(),
19            }
20        )
21    }
22}
23
24impl Error {
25    pub fn variant(&self) -> String {
26        match self {
27            Error::IOError(_) => "IOError",
28            Error::RuntimeError(_) => "RuntimeError",
29            Error::HeckError(_) => "HeckError",
30        }
31        .to_string()
32    }
33}
34
35impl std::error::Error for Error {}
36impl From<std::io::Error> for Error {
37    fn from(e: std::io::Error) -> Self {
38        Error::IOError(e.to_string())
39    }
40}
41// impl From<iocore::Error> for Error {
42//     fn from(e: iocore::Error) -> Self {
43//         Error::IOError(e.to_string())
44//     }
45// }
46pub type Result<T> = std::result::Result<T, Error>;
47
48#[derive(Debug, Clone)]
49pub enum Exit {
50    Success,
51    Error(Error),
52}
53impl std::process::Termination for Exit {
54    fn report(self) -> std::process::ExitCode {
55        match &self {
56            Exit::Success => std::process::ExitCode::from(0),
57            Exit::Error(error) => {
58                eprintln!("{}", error);
59                std::process::ExitCode::from(1)
60            },
61        }
62    }
63}
64impl<T> From<std::result::Result<T, Error>> for Exit {
65    fn from(result: std::result::Result<T, Error>) -> Exit {
66        match result {
67            Ok(_) => Exit::Success,
68            Err(e) => Exit::Error(e),
69        }
70    }
71}
72
73#[macro_export]
74macro_rules! function_name {
75    () => {{
76        fn f() {}
77        fn type_name_of<T>(_: T) -> &'static str {
78            std::any::type_name::<T>()
79        }
80        let name = type_name_of(f);
81        let name = name.strip_suffix("::f").unwrap();
82        name
83    }};
84}
85#[macro_export]
86macro_rules! traceback {
87    ($variant:ident, $error:expr ) => {{
88        let name = $crate::function_name!();
89        $crate::Error::$variant(format!("{} [{}:[{}:{}]]\n", $error, name, file!(), line!()))
90    }};
91    ($variant:ident, $format:literal, $arg:expr  ) => {{
92        $crate::traceback!($variant, format!($format, $arg))
93    }};
94    ($variant:ident, $format:literal, $( $arg:expr ),* ) => {{
95        $crate::traceback!($variant, format!($format, $($arg,)*))
96    }};
97}