bo4e_core/com/
validation_result.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
25#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
26#[cfg_attr(feature = "json-schema", schemars(rename = "Validierungsergebnis"))]
27#[serde(rename_all = "camelCase")]
28pub struct ValidationResult {
29 #[serde(flatten)]
31 pub meta: Bo4eMeta,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
35 #[cfg_attr(feature = "json-schema", schemars(rename = "validierungszeitpunkt"))]
36 pub validation_timestamp: Option<DateTime<Utc>>,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 #[cfg_attr(feature = "json-schema", schemars(rename = "gueltig"))]
41 pub is_valid: Option<bool>,
42
43 #[serde(skip_serializing_if = "Option::is_none")]
45 #[cfg_attr(feature = "json-schema", schemars(rename = "validierungsregel"))]
46 pub validation_rule_id: Option<String>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 #[cfg_attr(feature = "json-schema", schemars(rename = "regelbezeichnung"))]
51 pub validation_rule_name: Option<String>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
55 #[cfg_attr(feature = "json-schema", schemars(rename = "fehlercode"))]
56 pub error_code: Option<String>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 #[cfg_attr(feature = "json-schema", schemars(rename = "fehlermeldung"))]
61 pub error_message: Option<String>,
62
63 #[serde(skip_serializing_if = "Option::is_none")]
65 #[cfg_attr(feature = "json-schema", schemars(rename = "schweregrad"))]
66 pub severity: Option<String>,
67}
68
69impl Bo4eObject for ValidationResult {
70 fn type_name_german() -> &'static str {
71 "Validierungsergebnis"
72 }
73
74 fn type_name_english() -> &'static str {
75 "ValidationResult"
76 }
77
78 fn meta(&self) -> &Bo4eMeta {
79 &self.meta
80 }
81
82 fn meta_mut(&mut self) -> &mut Bo4eMeta {
83 &mut self.meta
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use chrono::TimeZone;
91
92 #[test]
93 fn test_validation_passed() {
94 let result = ValidationResult {
95 validation_timestamp: Some(Utc.with_ymd_and_hms(2024, 1, 15, 12, 0, 0).unwrap()),
96 is_valid: Some(true),
97 validation_rule_id: Some("RULE_001".to_string()),
98 ..Default::default()
99 };
100
101 let json = serde_json::to_string(&result).unwrap();
102 assert!(json.contains("true"));
103 assert!(json.contains("RULE_001"));
104 }
105
106 #[test]
107 fn test_validation_failed() {
108 let result = ValidationResult {
109 validation_timestamp: Some(Utc::now()),
110 is_valid: Some(false),
111 error_code: Some("E001".to_string()),
112 error_message: Some("Value out of range".to_string()),
113 severity: Some("ERROR".to_string()),
114 ..Default::default()
115 };
116
117 let json = serde_json::to_string(&result).unwrap();
118 assert!(json.contains("false"));
119 assert!(json.contains("E001"));
120 }
121
122 #[test]
123 fn test_roundtrip() {
124 let result = ValidationResult {
125 is_valid: Some(true),
126 validation_rule_name: Some("Range check".to_string()),
127 ..Default::default()
128 };
129
130 let json = serde_json::to_string(&result).unwrap();
131 let parsed: ValidationResult = serde_json::from_str(&json).unwrap();
132 assert_eq!(result, parsed);
133 }
134
135 #[test]
136 fn test_bo4e_object_impl() {
137 assert_eq!(ValidationResult::type_name_german(), "Validierungsergebnis");
138 assert_eq!(ValidationResult::type_name_english(), "ValidationResult");
139 }
140}