powerio_pkg/
validation.rs1use serde::{Deserialize, Serialize};
4
5use crate::diagnostics::{DiagnosticSeverity, StructuredDiagnostic};
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
10#[serde(rename_all = "snake_case")]
11pub enum ValidationStatus {
12 Ok,
13 Info,
14 Warning,
15 Error,
16 Fatal,
17}
18
19impl ValidationStatus {
20 fn from_severity(s: DiagnosticSeverity) -> Self {
21 match s {
22 DiagnosticSeverity::Debug => ValidationStatus::Ok,
23 DiagnosticSeverity::Info => ValidationStatus::Info,
24 DiagnosticSeverity::Warning => ValidationStatus::Warning,
25 DiagnosticSeverity::Error => ValidationStatus::Error,
26 DiagnosticSeverity::Fatal => ValidationStatus::Fatal,
27 }
28 }
29}
30
31#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
33#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
34pub struct ValidationCounts {
35 #[serde(default)]
36 pub fatal: u32,
37 #[serde(default)]
38 pub error: u32,
39 #[serde(default)]
40 pub warning: u32,
41 #[serde(default)]
42 pub info: u32,
43 #[serde(default)]
44 pub debug: u32,
45}
46
47impl ValidationCounts {
48 fn add(&mut self, s: DiagnosticSeverity) {
49 match s {
50 DiagnosticSeverity::Fatal => self.fatal += 1,
51 DiagnosticSeverity::Error => self.error += 1,
52 DiagnosticSeverity::Warning => self.warning += 1,
53 DiagnosticSeverity::Info => self.info += 1,
54 DiagnosticSeverity::Debug => self.debug += 1,
55 }
56 }
57}
58
59#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
61#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
62pub struct ValidationPass {
63 pub name: String,
64 pub status: ValidationStatus,
65}
66
67impl ValidationPass {
68 pub fn new(name: impl Into<String>, status: ValidationStatus) -> Self {
69 Self {
70 name: name.into(),
71 status,
72 }
73 }
74}
75
76#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
79#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
80pub struct ValidationSummary {
81 pub status: ValidationStatus,
82 pub counts: ValidationCounts,
83 #[serde(default, skip_serializing_if = "Vec::is_empty")]
84 pub passes: Vec<ValidationPass>,
85}
86
87impl ValidationSummary {
88 pub fn ok() -> Self {
90 Self {
91 status: ValidationStatus::Ok,
92 counts: ValidationCounts::default(),
93 passes: Vec::new(),
94 }
95 }
96
97 pub fn from_diagnostics(diagnostics: &[StructuredDiagnostic]) -> Self {
99 let mut counts = ValidationCounts::default();
100 let mut status = ValidationStatus::Ok;
101 for d in diagnostics {
102 counts.add(d.severity);
103 status = status.max(ValidationStatus::from_severity(d.severity));
104 }
105 Self {
106 status,
107 counts,
108 passes: Vec::new(),
109 }
110 }
111
112 #[must_use]
113 pub fn with_passes(mut self, passes: Vec<ValidationPass>) -> Self {
114 self.passes = passes;
115 self
116 }
117}