gitql_cli/
diagnostic_reporter.rs1use gitql_parser::diagnostic::Diagnostic;
2
3use termcolor::Color;
4
5use crate::colored_stream::ColoredStream;
6
7#[derive(Default)]
8pub struct DiagnosticReporter {
9 stdout: ColoredStream,
10}
11
12impl DiagnosticReporter {
13 pub fn report_diagnostic(&mut self, query: &str, diagnostic: Diagnostic) {
14 self.stdout.set_color(Some(Color::Red));
15 println!("[{}]: {}", diagnostic.label(), diagnostic.message());
16
17 if let Some(location) = diagnostic.location() {
18 println!(
19 " --> Location {}:{}",
20 location.line_start, location.column_start
21 );
22 }
23
24 if !query.is_empty() {
25 println!(" |");
26 if let Some(location) = diagnostic.location() {
27 let lines: Vec<&str> = query.split('\n').collect();
28 let end = u32::min(location.line_end, lines.len() as u32);
29 for zero_based_line_number in location.line_start - 1..end {
30 println!("-> | {}", lines[zero_based_line_number as usize]);
31 }
32
33 println!(" | ");
34 let column_s = location.column_start.saturating_sub(1) as usize;
35 print!(" | {}", &"-".repeat(column_s));
36
37 let diagnostic_length =
38 u32::max(1, location.column_end.saturating_sub(location.column_start)) as usize;
39
40 self.stdout.set_color(Some(Color::Yellow));
41 println!("{}", &"^".repeat(diagnostic_length));
42
43 self.stdout.set_color(Some(Color::Red));
44 }
45 println!(" |");
46 }
47
48 self.stdout.set_color(Some(Color::Cyan));
49 for help in diagnostic.helps() {
50 println!(" = Help: {help}");
51 }
52
53 self.stdout.set_color(Some(Color::Yellow));
54 for note in diagnostic.notes() {
55 println!(" = Note: {note}");
56 }
57
58 self.stdout.set_color(Some(Color::Blue));
59 if let Some(docs) = diagnostic.docs() {
60 println!(" = Docs: {docs}");
61 }
62
63 self.stdout.reset();
64 }
65}