#[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct SyntheticDiagnostic {
pub base_path: String,
pub file_path: String,
pub level: String,
pub message: String,
pub code: Option<SyntheticDiagnosticCode>,
pub spans: Vec<SyntheticDiagnosticSpan>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct SyntheticDiagnosticCode {
pub code: String,
pub explanation: Option<String>,
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct SyntheticDiagnosticSpan {
pub file_name: String,
pub byte_start: u32,
pub byte_end: u32,
pub line_start: u32,
pub line_end: u32,
pub column_start: u32,
pub column_end: u32,
pub suggested_replacement: Option<String>,
pub suggestion_applicability: Option<Applicability>,
}
#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub enum Applicability {
MachineApplicable,
MaybeIncorrect,
HasPlaceholders,
Unspecified,
}
#[cfg(feature = "server")]
mod convert {
use std::borrow::Cow;
use std::path::Path;
use super::super::messages;
use super::super::messages::CargoCheckMessage;
use super::super::messages::Diagnostic;
use super::SyntheticDiagnostic;
use super::SyntheticDiagnosticCode;
use super::SyntheticDiagnosticSpan;
impl SyntheticDiagnostic {
pub fn new(check: &CargoCheckMessage) -> Vec<Self> {
let mut result = vec![];
Self::all(
&Path::new(check.manifest_path.as_ref())
.parent()
.unwrap_or("/".as_ref())
.to_string_lossy(),
&check.target.src_path,
&[],
&check.message,
&mut result,
);
result.reverse();
return result;
}
fn all(
base_path: &str,
file_path: &str,
parent_spans: &[SyntheticDiagnosticSpan],
diagnostic: &Diagnostic,
result: &mut Vec<Self>,
) {
let spans = if diagnostic.spans.is_empty() {
parent_spans.to_vec()
} else {
diagnostic
.spans
.iter()
.map(|span| SyntheticDiagnosticSpan {
file_name: span.file_name.to_string(),
byte_start: span.byte_start,
byte_end: span.byte_end,
line_start: span.line_start,
line_end: span.line_end,
column_start: span.column_start,
column_end: span.column_end,
suggested_replacement: span
.suggested_replacement
.as_ref()
.map(Cow::to_string),
suggestion_applicability: span.suggestion_applicability.map(|a| match a {
messages::Applicability::MachineApplicable => {
super::Applicability::MachineApplicable
}
messages::Applicability::MaybeIncorrect => {
super::Applicability::MaybeIncorrect
}
messages::Applicability::HasPlaceholders => {
super::Applicability::HasPlaceholders
}
messages::Applicability::Unspecified => {
super::Applicability::Unspecified
}
}),
})
.collect()
};
for child in diagnostic.children.iter().rev() {
Self::all(base_path, file_path, &spans, child, result);
}
result.push(Self {
base_path: base_path.to_owned(),
file_path: file_path.to_owned(),
level: diagnostic.level.to_string(),
message: diagnostic.message.to_string(),
code: diagnostic
.code
.as_ref()
.map(|code| SyntheticDiagnosticCode {
code: code.code.to_string(),
explanation: code.explanation.as_ref().map(Cow::to_string),
}),
spans,
});
}
}
}