crate_compile_test/
cargo_messages.rs1use std::path::PathBuf;
2
3use steps::check_errors::{CompilerMessage, MessageLocation, MessageType};
4
5#[derive(Debug, Clone, PartialEq, Deserialize)]
6#[serde(rename_all = "lowercase")]
7pub enum DiagnosticLevel {
8 Error,
9 Warning,
10 Note,
11 Help,
12
13 #[serde(rename = "")]
14 Empty,
15}
16
17#[derive(Debug, Deserialize)]
18pub struct Diagnostic {
19 pub message: Option<DiagnosticMessage>,
20 pub reason: String,
21}
22
23#[derive(Debug, Deserialize, Clone)]
24pub struct DiagnosticMessage {
25 pub message: String,
26 pub level: DiagnosticLevel,
27 pub code: Option<DiagnosticCode>,
28 pub spans: Vec<DiagnosticSpan>,
29 pub children: Vec<DiagnosticMessage>,
30}
31
32#[derive(Debug, Deserialize, Clone)]
33pub struct DiagnosticSpan {
34 pub file_name: String,
35 pub line_start: usize,
36 pub is_primary: bool,
37}
38
39#[derive(Debug, Deserialize, Clone)]
40pub struct DiagnosticCode {
41 pub code: String,
42}
43
44impl Default for DiagnosticSpan {
45 fn default() -> Self {
46 DiagnosticSpan {
47 file_name: "unknown".into(),
48 line_start: 1,
49 is_primary: true,
50 }
51 }
52}
53
54impl<'a> From<&'a str> for DiagnosticLevel {
55 fn from(text: &str) -> Self {
56 match text {
57 "ERROR" => DiagnosticLevel::Error,
58 "WARNING" => DiagnosticLevel::Warning,
59 "NOTE" => DiagnosticLevel::Note,
60 "HELP" => DiagnosticLevel::Help,
61
62 _ => DiagnosticLevel::Empty,
63 }
64 }
65}
66
67impl Into<CompilerMessage> for DiagnosticMessage {
68 fn into(self) -> CompilerMessage {
69 let location = self.spans
70 .into_iter()
71 .filter(|item| item.is_primary)
72 .nth(0)
73 .map(|span| MessageLocation {
74 file: PathBuf::from(span.file_name),
75 line: span.line_start,
76 });
77
78 CompilerMessage {
79 message: MessageType::Text(self.message),
80 level: self.level,
81 code: self.code.map(|item| item.code),
82 location,
83 }
84 }
85}