Skip to main content

forge_ir/
diagnostic.rs

1//! Diagnostics and source locations.
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub struct Diagnostic {
7    pub severity: Severity,
8    /// Stable diagnostic code, e.g. `"rust-axum/E-UNTAGGED-UNION"`.
9    pub code: String,
10    pub message: String,
11    #[serde(default, skip_serializing_if = "Option::is_none")]
12    pub location: Option<SpecLocation>,
13    #[serde(default, skip_serializing_if = "Vec::is_empty")]
14    pub related: Vec<RelatedInfo>,
15    #[serde(default, skip_serializing_if = "Option::is_none")]
16    pub suggested_fix: Option<FixSuggestion>,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
20#[serde(rename_all = "kebab-case")]
21pub enum Severity {
22    Error,
23    Warning,
24    Info,
25    Hint,
26}
27
28#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
29pub struct RelatedInfo {
30    pub message: String,
31    #[serde(default, skip_serializing_if = "Option::is_none")]
32    pub location: Option<SpecLocation>,
33}
34
35#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
36pub struct FixSuggestion {
37    pub message: String,
38    pub edits: Vec<FixEdit>,
39}
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
42pub struct FixEdit {
43    pub location: SpecLocation,
44    pub replacement: String,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
48pub struct SpecLocation {
49    /// RFC 6901 JSON pointer, e.g. `/paths/~1pets/get`.
50    pub pointer: String,
51    #[serde(default, skip_serializing_if = "Option::is_none")]
52    pub file: Option<String>,
53}
54
55impl SpecLocation {
56    pub fn new(pointer: impl Into<String>) -> Self {
57        Self {
58            pointer: pointer.into(),
59            file: None,
60        }
61    }
62
63    pub fn with_file(pointer: impl Into<String>, file: impl Into<String>) -> Self {
64        Self {
65            pointer: pointer.into(),
66            file: Some(file.into()),
67        }
68    }
69}