shapemap/
validation_status.rs1use std::fmt::Display;
2
3use serde::Serialize;
4use serde_json::Value;
5
6#[derive(Debug, PartialEq, Clone, Serialize)]
8pub enum ValidationStatus {
9 Conformant(ConformantInfo),
10 NonConformant(NonConformantInfo),
11 Pending,
12 Inconsistent(ConformantInfo, NonConformantInfo),
13}
14
15impl ValidationStatus {
16 pub fn is_conformant(&self) -> bool {
17 matches!(self, ValidationStatus::Conformant(_))
18 }
19
20 pub fn is_non_conformant(&self) -> bool {
21 matches!(self, ValidationStatus::NonConformant(_))
22 }
23
24 pub fn is_pending(&self) -> bool {
25 matches!(self, ValidationStatus::Pending)
26 }
27
28 pub fn conformant(reason: String, value: Value) -> ValidationStatus {
29 ValidationStatus::Conformant(ConformantInfo {
30 reason,
31 app_info: value,
32 })
33 }
34
35 pub fn non_conformant(reason: String, value: Value) -> ValidationStatus {
36 ValidationStatus::NonConformant(NonConformantInfo {
37 reason,
38 app_info: value,
39 })
40 }
41
42 pub fn pending() -> ValidationStatus {
43 ValidationStatus::Pending
44 }
45
46 pub fn code(&self) -> String {
47 match self {
48 ValidationStatus::Conformant(_) => "conformant".to_string(),
49 ValidationStatus::NonConformant(_) => "nonconformant".to_string(),
50 ValidationStatus::Pending => "pending".to_string(),
51 ValidationStatus::Inconsistent(_, _) => "inconsistent".to_string(),
52 }
53 }
54
55 pub fn app_info(&self) -> Value {
56 match self {
57 ValidationStatus::Conformant(conformant_info) => conformant_info.app_info.clone(),
58 ValidationStatus::NonConformant(non_conformant_info) => {
59 non_conformant_info.app_info.clone()
60 }
61 ValidationStatus::Pending => serde_json::json!({ "status": "pending" }),
62 ValidationStatus::Inconsistent(conformant, non_conformant) => {
63 serde_json::json!({
64 "status": "inconsistent",
65 "conformant": conformant.app_info,
66 "non_conformant": non_conformant.app_info
67 })
68 }
69 }
70 }
71
72 pub fn reason(&self) -> String {
73 match self {
74 ValidationStatus::Conformant(conformant_info) => conformant_info.reason.clone(),
75 ValidationStatus::NonConformant(non_conformant_info) => {
76 non_conformant_info.reason.clone()
77 }
78 ValidationStatus::Pending => "Pending".to_string(),
79 ValidationStatus::Inconsistent(conformant, non_conformant) => {
80 format!(
81 "Conformant: {}, Non-conformant: {}",
82 conformant.reason, non_conformant.reason
83 )
84 }
85 }
86 }
87}
88
89impl Display for ValidationStatus {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 match self {
92 ValidationStatus::Conformant(conformant_info) => {
93 write!(f, "Conformant, reason: {conformant_info}")
94 }
95 ValidationStatus::NonConformant(non_conformant_info) => {
96 write!(f, "Non conformant, reason: {non_conformant_info}")
97 }
98 ValidationStatus::Pending => {
99 write!(f, "Pending")
100 }
101 ValidationStatus::Inconsistent(conformant, inconformant) => {
102 write!(
103 f,
104 "Inconsistent, conformant: {conformant}, inconformant: {inconformant}"
105 )
106 }
107 }
108 }
109}
110#[derive(Debug, PartialEq, Clone, Serialize)]
111pub struct ConformantInfo {
112 reason: String,
113 app_info: Value,
114}
115
116impl ConformantInfo {
117 pub fn merge(&self, other: ConformantInfo) -> ConformantInfo {
118 let merged_reason = format!("{}\n{}", self.reason, other.reason);
119 ConformantInfo {
120 reason: merged_reason,
121 app_info: self.app_info.clone(),
122 }
123 }
124}
125
126impl Display for ConformantInfo {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 write!(f, "{}", self.reason)
129 }
130}
131
132#[derive(Debug, PartialEq, Clone, Serialize)]
133pub struct NonConformantInfo {
134 reason: String,
135 app_info: Value,
136}
137
138impl Display for NonConformantInfo {
139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140 write!(f, "{}", self.reason)
141 }
142}