redispatch_xml/validation/
mod.rs1use crate::error::RedispatchXmlError;
12use crate::parse::Document;
13
14pub mod semantic;
15pub mod structural;
16
17#[derive(Debug, Clone, PartialEq, thiserror::Error)]
21pub enum ValidationError {
22 #[error("document identifier must be 1–35 characters, got {0}")]
23 DocumentIdLength(usize),
24 #[error("document version must be 1–999, got {0}")]
25 DocumentVersionRange(u32),
26 #[error("market participant ID must be exactly 13 decimal digits, got {0:?}")]
27 MarketParticipantIdFormat(String),
28 #[error("timestamp must be UTC, got offset {0}")]
29 TimestampNotUtc(String),
30 #[error("time interval end must be after start")]
31 TimeIntervalOrder,
32 #[error("{0}")]
33 Structural(String),
34 #[error("{0}")]
35 Semantic(String),
36}
37
38#[derive(Debug, Clone, PartialEq)]
40pub struct ValidationWarning(pub String);
41
42#[derive(Debug, Default, Clone)]
44pub struct ValidationResult {
45 pub warnings: Vec<ValidationWarning>,
47 pub errors: Vec<ValidationError>,
49}
50
51impl ValidationResult {
52 pub fn is_valid(&self) -> bool {
54 self.errors.is_empty()
55 }
56
57 pub fn into_result(mut self) -> Result<Vec<ValidationWarning>, ValidationError> {
59 if self.errors.is_empty() {
60 Ok(self.warnings)
61 } else {
62 Err(self.errors.remove(0))
63 }
64 }
65}
66
67impl std::fmt::Display for ValidationResult {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 if self.errors.is_empty() && self.warnings.is_empty() {
70 return write!(f, "ok");
71 }
72 for e in &self.errors {
73 writeln!(f, "error: {e}")?;
74 }
75 for w in &self.warnings {
76 writeln!(f, "warning: {}", w.0)?;
77 }
78 Ok(())
79 }
80}
81
82#[allow(unused_variables)]
97pub fn validate(doc: &Document) -> ValidationResult {
98 let mut result = ValidationResult::default();
99 structural::validate(doc, &mut result);
100 semantic::validate(doc, &mut result);
101 result
102}
103
104pub fn validate_structural<T>(doc: &T) -> Result<(), RedispatchXmlError>
109where
110 T: structural::ValidateStructural,
111{
112 let mut result = ValidationResult::default();
113 doc.validate_structural(&mut result);
114 result
115 .into_result()
116 .map(|_| ())
117 .map_err(|e| RedispatchXmlError::StructuralError(e.to_string()))
118}