crate_compile_test/
cargo_messages.rs

1use 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}