1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//! Standard error codes for validation issues.
//!
//! Error codes follow a prefix convention:
//! - `STR0xx`: Structure validation
//! - `FMT0xx`: Format validation
//! - `COD0xx`: Code value validation
//! - `AHB0xx`: AHB condition rule validation
/// Standard error codes for validation issues.
pub struct ErrorCodes;
impl ErrorCodes {
// --- Structure validation (STR001-STR099) ---
/// A mandatory segment is missing.
pub const MISSING_MANDATORY_SEGMENT: &'static str = "STR001";
/// Segment repetitions exceed the MIG MaxRep count.
pub const MAX_REPETITIONS_EXCEEDED: &'static str = "STR002";
/// Unexpected segment found (not defined in MIG for this message type).
pub const UNEXPECTED_SEGMENT: &'static str = "STR003";
/// Segments are in wrong order according to the MIG.
pub const WRONG_SEGMENT_ORDER: &'static str = "STR004";
/// A mandatory segment group is missing.
pub const MISSING_MANDATORY_GROUP: &'static str = "STR005";
/// Segment group repetitions exceed MaxRep count.
pub const GROUP_MAX_REP_EXCEEDED: &'static str = "STR006";
/// UNT segment count does not match the actual number of segments.
pub const UNT_SEGMENT_COUNT_MISMATCH: &'static str = "STR007";
/// A segment was present in the EDIFACT input but the PID-filtered MIG
/// has no slot for it. The assembler advanced past it (skip mode on),
/// so subsequent legitimate content still assembled, but the message
/// contains data outside the AHB and callers should surface it.
pub const SKIPPED_UNKNOWN_SEGMENT: &'static str = "STR008";
// --- Format validation (FMT001-FMT099) ---
/// Value exceeds maximum allowed length.
pub const VALUE_TOO_LONG: &'static str = "FMT001";
/// Value does not match required numeric format.
pub const INVALID_NUMERIC_FORMAT: &'static str = "FMT002";
/// Value does not match required alphanumeric format.
pub const INVALID_ALPHANUMERIC_FORMAT: &'static str = "FMT003";
/// Invalid date/time format.
pub const INVALID_DATE_FORMAT: &'static str = "FMT004";
/// Value is shorter than minimum required length.
pub const VALUE_TOO_SHORT: &'static str = "FMT005";
/// A required element is empty.
pub const REQUIRED_ELEMENT_EMPTY: &'static str = "FMT006";
// --- Code validation (COD001-COD099) ---
/// Code value is not in the allowed code list for this element.
pub const INVALID_CODE_VALUE: &'static str = "COD001";
/// Code value is not allowed for this specific Pruefidentifikator.
pub const CODE_NOT_ALLOWED_FOR_PID: &'static str = "COD002";
/// The answer is not a code of the EBD or Codeliste named beside it.
pub const ANSWER_NOT_IN_LIST: &'static str = "COD003";
// --- AHB validation (AHB001-AHB999) ---
/// A field required by the AHB for this PID is missing.
pub const MISSING_REQUIRED_FIELD: &'static str = "AHB001";
/// A field is present but not allowed by the AHB for this PID.
pub const FIELD_NOT_ALLOWED_FOR_PID: &'static str = "AHB002";
/// A conditional AHB rule is violated.
pub const CONDITIONAL_RULE_VIOLATION: &'static str = "AHB003";
/// The Pruefidentifikator is unknown / not supported.
pub const UNKNOWN_PRUEFIDENTIFIKATOR: &'static str = "AHB004";
/// A condition expression could not be fully evaluated (Unknown result).
pub const CONDITION_UNKNOWN: &'static str = "AHB005";
/// Package cardinality constraint violated: count of present codes outside [min..max].
pub const PACKAGE_CARDINALITY_VIOLATION: &'static str = "AHB006";
/// A group or segment allowed once per transaction is sent more often.
pub const REPEATED_IN_TRANSACTION: &'static str = "AHB007";
// Consistency within the message (CON)
/// A period ends before, or as, it begins (APERAK Z34).
pub const INTERVAL_NOT_POSITIVE: &'static str = "CON001";
/// A reference within a transaction names nothing in it (APERAK Z21).
pub const REFERENCE_NOT_FOUND: &'static str = "CON002";
// Mapping between BO4E and EDIFACT (MAP)
/// A BO4E field that the EDIFACT rendered from it does not carry.
pub const BO4E_FIELD_DROPPED: &'static str = "MAP001";
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_code_prefixes() {
assert!(ErrorCodes::MISSING_MANDATORY_SEGMENT.starts_with("STR"));
assert!(ErrorCodes::VALUE_TOO_LONG.starts_with("FMT"));
assert!(ErrorCodes::INVALID_CODE_VALUE.starts_with("COD"));
assert!(ErrorCodes::MISSING_REQUIRED_FIELD.starts_with("AHB"));
}
#[test]
fn test_all_codes_are_unique() {
let codes = [
ErrorCodes::MISSING_MANDATORY_SEGMENT,
ErrorCodes::MAX_REPETITIONS_EXCEEDED,
ErrorCodes::UNEXPECTED_SEGMENT,
ErrorCodes::WRONG_SEGMENT_ORDER,
ErrorCodes::MISSING_MANDATORY_GROUP,
ErrorCodes::GROUP_MAX_REP_EXCEEDED,
ErrorCodes::UNT_SEGMENT_COUNT_MISMATCH,
ErrorCodes::SKIPPED_UNKNOWN_SEGMENT,
ErrorCodes::VALUE_TOO_LONG,
ErrorCodes::INVALID_NUMERIC_FORMAT,
ErrorCodes::INVALID_ALPHANUMERIC_FORMAT,
ErrorCodes::INVALID_DATE_FORMAT,
ErrorCodes::VALUE_TOO_SHORT,
ErrorCodes::REQUIRED_ELEMENT_EMPTY,
ErrorCodes::INVALID_CODE_VALUE,
ErrorCodes::CODE_NOT_ALLOWED_FOR_PID,
ErrorCodes::MISSING_REQUIRED_FIELD,
ErrorCodes::FIELD_NOT_ALLOWED_FOR_PID,
ErrorCodes::CONDITIONAL_RULE_VIOLATION,
ErrorCodes::UNKNOWN_PRUEFIDENTIFIKATOR,
ErrorCodes::CONDITION_UNKNOWN,
ErrorCodes::PACKAGE_CARDINALITY_VIOLATION,
ErrorCodes::REPEATED_IN_TRANSACTION,
];
let unique: std::collections::HashSet<&str> = codes.iter().copied().collect();
assert_eq!(codes.len(), unique.len(), "Duplicate error codes found");
}
}