odcs 0.8.0

Reference implementation of the Open Data Contract Standard (ODCS)
Documentation
//! A single diagnostic message.

use super::{DiagnosticCategory, DiagnosticStage, Severity, ValidationPhase};

/// A spec-level diagnostic record.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct Diagnostic {
    /// Stable `odcs:` diagnostic identifier.
    pub id: String,
    /// Diagnostic severity.
    pub severity: Severity,
    /// Originating processing stage.
    pub stage: DiagnosticStage,
    /// Diagnostic category.
    pub category: DiagnosticCategory,
    /// Human-readable message.
    pub message: String,
    /// Affected object reference, when applicable.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub object_ref: Option<String>,
    /// Suggested remediation, when practical.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub remediation: Option<String>,
    /// Validation pipeline phase that produced this diagnostic.
    #[serde(rename = "validationPhase", skip_serializing_if = "Option::is_none")]
    pub validation_phase: Option<ValidationPhase>,
}

impl Diagnostic {
    /// Creates a new diagnostic.
    #[must_use]
    pub fn new(
        id: impl Into<String>,
        severity: Severity,
        stage: DiagnosticStage,
        category: DiagnosticCategory,
        message: impl Into<String>,
    ) -> Self {
        Self {
            id: id.into(),
            severity,
            stage,
            category,
            message: message.into(),
            object_ref: None,
            remediation: None,
            validation_phase: None,
        }
    }

    /// Creates an error-level diagnostic.
    #[must_use]
    pub fn error(
        id: impl Into<String>,
        category: DiagnosticCategory,
        stage: DiagnosticStage,
        message: impl Into<String>,
    ) -> Self {
        Self::new(id, Severity::Error, stage, category, message)
    }

    /// Sets the affected object reference.
    #[must_use]
    pub fn with_object_ref(mut self, object_ref: impl Into<String>) -> Self {
        self.object_ref = Some(object_ref.into());
        self
    }

    /// Sets remediation guidance.
    #[must_use]
    pub fn with_remediation(mut self, remediation: impl Into<String>) -> Self {
        self.remediation = Some(remediation.into());
        self
    }

    /// Sets the validation pipeline phase.
    #[must_use]
    pub fn with_validation_phase(mut self, phase: ValidationPhase) -> Self {
        self.validation_phase = Some(phase);
        self
    }
}