daedalus_planner/
diagnostics.rs

1use serde::{Deserialize, Serialize};
2
3/// Where a diagnostic applies.
4///
5/// ```
6/// use daedalus_planner::DiagnosticSpan;
7/// let span = DiagnosticSpan { pass: "validate".into(), node: Some("n1".into()), port: None };
8/// assert_eq!(span.pass, "validate");
9/// ```
10#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
11pub struct DiagnosticSpan {
12    pub pass: String,
13    pub node: Option<String>,
14    pub port: Option<String>,
15}
16
17/// Planner diagnostic codes (non-exhaustive).
18///
19/// ```
20/// use daedalus_planner::DiagnosticCode;
21/// let code = DiagnosticCode::NodeMissing;
22/// assert_eq!(format!("{code:?}"), "NodeMissing");
23/// ```
24#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
25#[non_exhaustive]
26pub enum DiagnosticCode {
27    NodeMissing,
28    PortMissing,
29    UnresolvedInput,
30    ConverterMissing,
31    TypeMismatch,
32    GpuUnsupported,
33    ScheduleConflict,
34    LintWarning,
35}
36
37/// Planner diagnostic entry.
38///
39/// ```
40/// use daedalus_planner::{Diagnostic, DiagnosticCode};
41/// let diag = Diagnostic::new(DiagnosticCode::PortMissing, "missing")
42///     .in_pass("validate")
43///     .at_node("node");
44/// assert_eq!(diag.span.pass, "validate");
45/// ```
46#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
47pub struct Diagnostic {
48    pub code: DiagnosticCode,
49    pub message: String,
50    pub span: DiagnosticSpan,
51}
52
53impl Diagnostic {
54    /// Create a diagnostic with a code and message.
55    pub fn new(code: DiagnosticCode, message: impl Into<String>) -> Self {
56        Self {
57            code,
58            message: message.into(),
59            span: DiagnosticSpan {
60                pass: String::new(),
61                node: None,
62                port: None,
63            },
64        }
65    }
66
67    /// Set the pass name that emitted this diagnostic.
68    pub fn in_pass(mut self, pass: &'static str) -> Self {
69        self.span.pass = pass.to_string();
70        self
71    }
72
73    /// Attach node context for this diagnostic.
74    pub fn at_node(mut self, node: impl Into<String>) -> Self {
75        self.span.node = Some(node.into());
76        self
77    }
78
79    /// Attach port context for this diagnostic.
80    pub fn at_port(mut self, port: impl Into<String>) -> Self {
81        self.span.port = Some(port.into());
82        self
83    }
84}