1use crate::Severity;
2use crate::Severity::{Error, Info, Warning};
3use colored::{Color, Colorize};
4use std::fmt::{Display, Formatter};
5
6#[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 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 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 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 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 pub fn severity(&self) -> Severity {
70 self.severity
71 }
72
73 #[must_use]
75 pub fn id(&self) -> &str {
76 self.id.as_str()
77 }
78
79 #[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}