corn_cli/
error.rs

1use colored::Colorize;
2use corn::error::Error as CornError;
3use std::fmt::{Display, Formatter};
4use std::io;
5
6#[derive(Debug)]
7pub enum Error {
8    /// Error from the Corn parser
9    Corn(CornError),
10    /// Error while reading the input file from disk
11    ReadingFile(io::Error),
12    /// Error when serializing output
13    Serializing(String),
14}
15
16pub trait ExitCode {
17    fn get_exit_code(&self) -> i32;
18}
19
20impl ExitCode for CornError {
21    fn get_exit_code(&self) -> i32 {
22        match self {
23            CornError::Io(_) => 3,
24            CornError::ParserError(_) => 1,
25            CornError::InputResolveError(_) => 2,
26            CornError::InvalidPathError(_) => 6,
27            CornError::InvalidSpreadError(_) => 7,
28            CornError::InvalidInterpolationError(_) => 8,
29            CornError::DeserializationError(_) => 5,
30        }
31    }
32}
33
34impl ExitCode for Error {
35    fn get_exit_code(&self) -> i32 {
36        match self {
37            Error::Corn(err) => err.get_exit_code(),
38            Error::ReadingFile(_) => 3,
39            Error::Serializing(_) => 4,
40        }
41    }
42}
43
44impl std::error::Error for Error {}
45
46impl From<io::Error> for Error {
47    fn from(err: io::Error) -> Self {
48        Self::ReadingFile(err)
49    }
50}
51
52impl From<serde_json::Error> for Error {
53    fn from(err: serde_json::Error) -> Self {
54        Self::Serializing(err.to_string())
55    }
56}
57
58impl From<serde_yaml::Error> for Error {
59    fn from(err: serde_yaml::Error) -> Self {
60        Self::Serializing(err.to_string())
61    }
62}
63
64impl From<toml_edit::ser::Error> for Error {
65    fn from(err: toml_edit::ser::Error) -> Self {
66        Self::Serializing(err.to_string())
67    }
68}
69
70impl Display for Error {
71    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72        match self {
73            Error::Corn(err) => write!(f, "{err}"),
74            Error::ReadingFile(err) => write!(f, "{err}"),
75            Error::Serializing(err) => write!(
76                f,
77                "The input could not be serialized into the requested output format:\n\t{err}"
78            ),
79        }
80    }
81}
82
83/// Pretty-prints `message` to `stderr`.
84/// If `context` is supplied,
85/// it will be appended to the first line.
86pub fn print_err(message: &str, context: Option<String>) {
87    if let Some(context) = context {
88        eprintln!("{} {}:", "An error occurred".red(), context.red());
89    } else {
90        eprintln!("{}", "An error occurred:".red());
91    }
92
93    eprintln!("\t{}", message.red().bold());
94}