redispatch_xml/validation/
structural.rs1use super::{ValidationError, ValidationResult};
11use crate::parse::Document;
12use crate::types::{DocumentId, DocumentVersion, MarketParticipantId, TimeInterval, UtcDateTime};
13
14pub trait ValidateStructural {
18 fn validate_structural(&self, result: &mut ValidationResult);
20}
21
22pub(crate) fn check_document_id(id: &DocumentId, result: &mut ValidationResult) {
26 let len = id.as_str().len();
27 if len == 0 || len > 35 {
28 result.errors.push(ValidationError::DocumentIdLength(len));
29 }
30}
31
32pub(crate) fn check_document_version(v: &DocumentVersion, result: &mut ValidationResult) {
34 let n = v.get() as u32;
35 if n == 0 || n > 999 {
36 result.errors.push(ValidationError::DocumentVersionRange(n));
37 }
38}
39
40pub(crate) fn check_participant_id(id: &MarketParticipantId, result: &mut ValidationResult) {
42 let s = id.as_str();
43 if s.len() != 13 || !s.bytes().all(|b| b.is_ascii_digit()) {
44 result
45 .errors
46 .push(ValidationError::MarketParticipantIdFormat(s.to_string()));
47 }
48}
49
50pub(crate) fn check_utc_offset(ts: &UtcDateTime, result: &mut ValidationResult) {
55 let inner = ts.inner();
59 if inner.offset() != time::UtcOffset::UTC {
60 result
61 .errors
62 .push(ValidationError::TimestampNotUtc(inner.to_string()));
63 }
64}
65
66pub(crate) fn check_time_interval(interval: &TimeInterval, result: &mut ValidationResult) {
68 if interval.end <= interval.start {
69 result.errors.push(ValidationError::TimeIntervalOrder);
70 }
71}
72
73pub fn validate(doc: &Document, result: &mut ValidationResult) {
77 match doc {
78 Document::Activation(d) => validate_activation(d, result),
79 Document::PlannedResourceSchedule(d) => validate_prs(d, result),
80 Document::Acknowledgement(d) => validate_ack(d, result),
81 Document::NetworkConstraint(d) => validate_ncd(d, result),
82 Document::Kostenblatt(d) => validate_kostenblatt(d, result),
83 Document::Kaskade(d) => {
85 check_document_id(&d.m_rid, result);
86 check_document_version(&d.revision_number, result);
87 }
88 Document::StatusRequest(d) => {
89 check_document_id(&d.m_rid, result);
90 }
91 Document::Unavailability(d) => {
92 check_document_id(&d.m_rid, result);
93 }
94 Document::Stammdaten(d) => {
95 check_document_id(&d.document_identification, result);
96 check_participant_id(&d.sender.code, result);
97 check_participant_id(&d.empfaenger.code, result);
98 }
99 }
100}
101
102use crate::documents::kostenblatt::Kostenblatt;
103use crate::documents::{
104 AcknowledgementDocument, ActivationDocument, NetworkConstraintDocument,
105 PlannedResourceScheduleDocument,
106};
107
108fn validate_activation(d: &ActivationDocument, result: &mut ValidationResult) {
109 check_document_id(&d.document_identification.v, result);
110 check_document_version(&d.document_version.v, result);
111 check_participant_id(&d.sender_identification.v, result);
112 check_participant_id(&d.receiver_identification.v, result);
113 check_utc_offset(&d.creation_date_time.v, result);
114 check_time_interval(&d.activation_time_interval.v, result);
115}
116
117fn validate_prs(d: &PlannedResourceScheduleDocument, result: &mut ValidationResult) {
118 check_document_id(&d.document_identification.v, result);
119 check_document_version(&d.document_version.v, result);
120 check_participant_id(&d.sender_identification.v, result);
121 check_participant_id(&d.receiver_identification.v, result);
122 check_utc_offset(&d.document_date_time.v, result);
123 check_time_interval(&d.time_period_covered.v, result);
124}
125
126fn validate_ack(d: &AcknowledgementDocument, result: &mut ValidationResult) {
127 check_document_id(&d.document_identification.v, result);
128 check_participant_id(&d.sender_identification.v, result);
129 check_participant_id(&d.receiver_identification.v, result);
130 check_utc_offset(&d.document_date_time.v, result);
131}
132
133fn validate_ncd(d: &NetworkConstraintDocument, result: &mut ValidationResult) {
134 check_document_id(&d.document_identification.v, result);
135 check_document_version(&d.document_version.v, result);
136 check_participant_id(&d.sender_identification.v, result);
137 check_participant_id(&d.receiver_identification.v, result);
138 check_utc_offset(&d.document_date_time.v, result);
139 check_time_interval(&d.time_period_covered.v, result);
140}
141
142fn validate_kostenblatt(d: &Kostenblatt, result: &mut ValidationResult) {
143 check_document_id(&d.document_identification.v, result);
144 check_document_version(&d.document_version.v, result);
145 check_participant_id(&d.sender_identification.v, result);
146 check_participant_id(&d.receiver_identification.v, result);
147 check_utc_offset(&d.document_date_time.v, result);
148 check_time_interval(&d.time_period_covered.v, result);
149}