mit_commit_message_lints/console/
style.rs1use std::fmt::Display;
4
5use comfy_table::{
6 Attribute, Cell, ContentArrangement, Table, modifiers::UTF8_ROUND_CORNERS, presets::UTF8_FULL,
7};
8use miette::{Diagnostic, GraphicalReportHandler, Severity};
9use mit_lint::{Lint, Lints};
10use thiserror::Error;
11
12use crate::mit::Authors;
13
14pub fn success(success: &str, tip: &str) {
20 let mut out = String::new();
21 GraphicalReportHandler::default()
22 .render_report(
23 &mut out,
24 &Success {
25 success: success.to_string(),
26 help: Some(tip),
27 },
28 )
29 .unwrap();
30 println!("{out}");
31}
32
33#[derive(Error, Debug)]
34#[error("{success}")]
35struct Success<'a> {
36 success: String,
37 help: Option<&'a str>,
38}
39
40impl Diagnostic for Success<'_> {
41 fn severity(&self) -> Option<Severity> {
42 Some(Severity::Advice)
43 }
44
45 fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
46 self.help
47 .map(|x| Box::new(x.to_string()) as Box<dyn Display>)
48 }
49}
50
51#[derive(Error, Debug)]
52#[error("{warning}")]
53struct Warning<'a> {
54 warning: String,
55 help: Option<&'a str>,
56}
57
58impl Diagnostic for Warning<'_> {
59 fn severity(&self) -> Option<Severity> {
60 Some(Severity::Warning)
61 }
62
63 fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
64 self.help
65 .map(|x| Box::new(x.to_string()) as Box<dyn Display>)
66 }
67}
68
69pub fn warning(warning: &str, tip: Option<&str>) {
75 let mut out = String::new();
76 GraphicalReportHandler::default()
77 .render_report(
78 &mut out,
79 &Warning {
80 warning: warning.to_string(),
81 help: tip,
82 },
83 )
84 .unwrap();
85 eprintln!("{out}");
86}
87
88pub fn to_be_piped(output: &str) {
90 println!("{output}");
91}
92
93pub fn lint_table(list: &Lints, enabled: &Lints) {
95 let mut table = Table::new();
96 table
97 .load_preset(UTF8_FULL)
98 .apply_modifier(UTF8_ROUND_CORNERS)
99 .set_content_arrangement(ContentArrangement::Dynamic)
100 .set_header(vec!["Lint", "Status"]);
101
102 let enabled_set: std::collections::HashSet<Lint> = enabled.clone().into_iter().collect();
103
104 let rows: Table = list.clone().into_iter().fold(table, |mut table, lint| {
105 table.add_row(vec![
106 lint.name(),
107 if enabled_set.contains(&lint) {
108 "enabled"
109 } else {
110 "disabled"
111 },
112 ]);
113 table
114 });
115
116 println!("{rows}");
117}
118
119#[must_use]
121pub fn author_table(authors: &Authors<'_>) -> String {
122 let mut table = Table::new();
123 table
124 .load_preset(UTF8_FULL)
125 .apply_modifier(UTF8_ROUND_CORNERS)
126 .set_content_arrangement(ContentArrangement::Dynamic)
127 .set_header(vec!["Initial", "Name", "Email", "Signing Key"]);
128
129 let rows: Table = authors
130 .authors
131 .iter()
132 .fold(table, |mut table, (initial, author)| {
133 table.add_row(vec![
134 Cell::new(initial),
135 Cell::new(author.name()),
136 Cell::new(author.email()),
137 author.signingkey().map_or_else(
138 || Cell::new("None".to_string()).add_attributes(vec![Attribute::Italic]),
139 Cell::new,
140 ),
141 ]);
142 table
143 });
144
145 format!("{rows}")
146}
147
148#[cfg(test)]
149mod tests {
150 use miette::{Diagnostic, Severity};
151
152 use super::{Success, Warning};
153
154 #[test]
155 fn success_has_advice_severity() {
156 let success = Success {
157 success: "done".into(),
158 help: Some("tip"),
159 };
160 assert_eq!(
161 success.severity(),
162 Some(Severity::Advice),
163 "Expected success to have Advice severity"
164 );
165 }
166
167 #[test]
168 fn success_returns_help_when_present() {
169 let success = Success {
170 success: "done".into(),
171 help: Some("use --force"),
172 };
173 assert!(
174 success.help().is_some(),
175 "Expected help to be present when one is provided"
176 );
177 }
178
179 #[test]
180 fn success_returns_no_help_when_absent() {
181 let success = Success {
182 success: "done".into(),
183 help: None,
184 };
185 assert!(
186 success.help().is_none(),
187 "Expected help to be absent when none is provided"
188 );
189 }
190
191 #[test]
192 fn warning_has_warning_severity() {
193 let warning = Warning {
194 warning: "careful".into(),
195 help: Some("tip"),
196 };
197 assert_eq!(
198 warning.severity(),
199 Some(Severity::Warning),
200 "Expected warning to have Warning severity"
201 );
202 }
203
204 #[test]
205 fn warning_returns_help_when_present() {
206 let warning = Warning {
207 warning: "careful".into(),
208 help: Some("check config"),
209 };
210 assert!(
211 warning.help().is_some(),
212 "Expected help to be present when one is provided"
213 );
214 }
215
216 #[test]
217 fn warning_returns_no_help_when_absent() {
218 let warning = Warning {
219 warning: "careful".into(),
220 help: None,
221 };
222 assert!(
223 warning.help().is_none(),
224 "Expected help to be absent when none is provided"
225 );
226 }
227}