Skip to main content

clerr/
code.rs

1use crate::Severity;
2use crate::Severity::{Error, Info, Warning};
3use colored::{Color, Colorize};
4use std::fmt::{Display, Formatter};
5
6/// A command-line report code with a severity, identifier, and message.
7///
8/// # Display
9///
10/// ```text
11/// severity[id]: message
12/// ```
13#[must_use]
14#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
15pub struct Code {
16    severity: Severity,
17    id: String,
18    message: String,
19}
20
21impl Code {
22    //! Construction
23
24    /// Creates a new command-line report code.
25    pub fn new<S0, S1>(severity: Severity, id: S0, message: S1) -> Self
26    where
27        S0: Into<String>,
28        S1: Into<String>,
29    {
30        Self {
31            severity,
32            id: id.into(),
33            message: message.into(),
34        }
35    }
36
37    /// Creates a new error code.
38    pub fn error<S0, S1>(id: S0, message: S1) -> Self
39    where
40        S0: Into<String>,
41        S1: Into<String>,
42    {
43        Self::new(Error, id, message)
44    }
45
46    /// Creates a new warning code.
47    pub fn warning<S0, S1>(id: S0, message: S1) -> Self
48    where
49        S0: Into<String>,
50        S1: Into<String>,
51    {
52        Self::new(Warning, id, message)
53    }
54
55    /// Creates a new info code.
56    pub fn info<S0, S1>(id: S0, message: S1) -> Self
57    where
58        S0: Into<String>,
59        S1: Into<String>,
60    {
61        Self::new(Info, id, message)
62    }
63}
64
65impl Code {
66    //! Properties
67
68    /// Gets the severity.
69    pub fn severity(&self) -> Severity {
70        self.severity
71    }
72
73    /// Gets the identifier.
74    #[must_use]
75    pub fn id(&self) -> &str {
76        self.id.as_str()
77    }
78
79    /// Gets the message.
80    #[must_use]
81    pub fn message(&self) -> &str {
82        self.message.as_str()
83    }
84}
85
86impl Display for Code {
87    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
88        let color: Color = self.severity.color();
89        write!(
90            f,
91            "{}{}{}{}{}",
92            self.severity,
93            "[".color(color),
94            self.id.color(color),
95            "]: ".color(color),
96            self.message.bright_white().bold()
97        )
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use crate::Code;
104    use colored::Colorize;
105
106    #[test]
107    fn display() {
108        let code: Code = Code::error("E123", "the error message");
109        let result: String = code.to_string();
110        let expected: String = [
111            "error".bright_red(),
112            "[".bright_red(),
113            "E123".bright_red(),
114            "]: ".bright_red(),
115            "the error message".bright_white().bold(),
116        ]
117        .iter()
118        .map(|s| s.to_string())
119        .collect();
120        assert_eq!(result, expected);
121    }
122}