#[non_exhaustive]pub struct ValidationIssue {Show 13 fields
pub error_code: Option<&'static str>,
pub severity: ValidationSeverity,
pub message: String,
pub offset: Option<usize>,
pub segment_tag: Option<String>,
pub rule_id: Option<String>,
pub element_index: Option<u8>,
pub component_index: Option<u8>,
pub segment_occurrence: Option<u16>,
pub message_ref: Option<String>,
pub suggestion: Option<String>,
pub segment_group: Option<Arc<str>>,
pub context: Vec<(String, String)>,
}Expand description
A structured validation issue.
Marked #[non_exhaustive] so that new diagnostic fields (e.g. segment_group)
can be added in future releases without breaking downstream code that constructs
issues via struct literals. Always use ValidationIssue::new + builder
methods (with_*) rather than constructing directly.
§Rule ID prefix convention
The rule_id field doubles as a lightweight metadata carrier when no full
context map is needed. Use a namespaced, structured prefix so consumers can
extract domain-specific information without parsing the human-readable message:
"<PACK>-<SCOPE>-<TAG>-<STATUS>"
^^^^^^^^ — identifies the pack / profile (e.g. "AHB-13001")
^^^^^^^ — identifies the rule scope (e.g. "SG5", "BGM")
^^^ — identifies the affected segment
^^^^^^^ — M/C/... status or short discriminatorExample: "AHB-13001-BGM-M" encodes the AHB process identifier (13001),
the affected segment (BGM), and the mandatory status (M). Downstream code
can extract the PID with a simple string split:
if let Some(pid) = rule_id.strip_prefix("AHB-").and_then(|s| s.splitn(2, '-').next()) {
println!("process identifier: {pid}"); // "13001"
}For truly arbitrary domain metadata, use the context map and
with_context_entry.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.error_code: Option<&'static str>Stable error code, if known.
Not preserved across serialization round-trips: deserialized issues
always have error_code = None because error codes are compile-time
library constants, not external data.
severity: ValidationSeverityThe severity of this issue.
message: StringThe error or warning message.
offset: Option<usize>Byte offset in the source (if available).
segment_tag: Option<String>Segment tag involved (if known).
rule_id: Option<String>Profile/MIG rule identifier, if applicable.
By convention, rule IDs are namespaced hierarchically so that downstream
code can extract domain-specific metadata (pack name, process ID, rule scope)
from the string. See the ValidationIssue type-level docs for the
recommended naming convention.
element_index: Option<u8>Element index (0-based), if known.
u8 is sufficient: EDIFACT segments have at most 99 data elements per
the UN/EDIFACT standard, so an index fits comfortably in one byte.
component_index: Option<u8>Component index (0-based), if known.
u8 is sufficient: composite data elements have at most 99 components
per the UN/EDIFACT standard.
segment_occurrence: Option<u16>Zero-based occurrence index among segments with the same tag in the message.
When multiple segments share the same tag (e.g. repeated DTM lines),
this field indicates which occurrence (0 = first) was the source of
this issue. None when occurrence tracking is not available for this rule.
message_ref: Option<String>Message reference (UNH element 0, DE 0062) that this issue belongs to.
Populated automatically when the context was built with
ValidationContextBuilder::with_message_ref. Useful in batch processing
where many messages are validated and issues from different messages must
be correlated back to the originating UNH/UNT envelope.
suggestion: Option<String>Suggested remediation (if available).
segment_group: Option<Arc<str>>Segment group (e.g. "SG6") in which the issue occurred, if known.
Populated by group-aware rule functions when they evaluate sub-slices of a
crate::group::SegmentGroupIndexed tree. None for flat-segment rules
that do not have group context.
context: Vec<(String, String)>Arbitrary domain-specific key-value metadata attached to this issue.
Use this for information that does not fit into the structured fields above — for example the PID a downstream MIG crate is validating against, a trading-partner identifier, or a document UUID:
let issue = ValidationIssue::new(ValidationSeverity::Error, "BGM code invalid")
.with_rule_id("AHB-13001-BGM-M")
.with_context_entry("pid", "13001")
.with_context_entry("partner", "9900123456789");
assert_eq!(issue.context_get("pid"), Some("13001"));The vec is empty by default and is never populated by the built-in rules; it is reserved exclusively for caller-supplied metadata.
Entries are stored in insertion order; duplicate keys are allowed and
context_get returns the first match.
with_context_entry uses upsert semantics
(updates an existing key in place rather than duplicating it).
Implementations§
Source§impl ValidationIssue
impl ValidationIssue
Sourcepub fn new(severity: ValidationSeverity, message: impl Into<String>) -> Self
pub fn new(severity: ValidationSeverity, message: impl Into<String>) -> Self
Create a new validation issue.
Sourcepub fn with_error_code(self, code: &'static str) -> Self
pub fn with_error_code(self, code: &'static str) -> Self
Set stable error code metadata.
Sourcepub fn with_offset(self, offset: usize) -> Self
pub fn with_offset(self, offset: usize) -> Self
Set the byte offset for this issue.
Sourcepub fn with_segment(self, tag: impl Into<String>) -> Self
pub fn with_segment(self, tag: impl Into<String>) -> Self
Set the segment tag for this issue.
Sourcepub fn with_rule_id(self, rule_id: impl Into<String>) -> Self
pub fn with_rule_id(self, rule_id: impl Into<String>) -> Self
Set the profile/MIG rule identifier for this issue.
Sourcepub fn with_element_index(self, element_index: u8) -> Self
pub fn with_element_index(self, element_index: u8) -> Self
Set the element index (0-based) for this issue.
Sourcepub fn with_component_index(self, component_index: u8) -> Self
pub fn with_component_index(self, component_index: u8) -> Self
Set the component index (0-based) for this issue.
Sourcepub fn with_suggestion(self, suggestion: impl Into<String>) -> Self
pub fn with_suggestion(self, suggestion: impl Into<String>) -> Self
Set a suggestion for resolving this issue.
Sourcepub fn with_segment_occurrence(self, occurrence: u16) -> Self
pub fn with_segment_occurrence(self, occurrence: u16) -> Self
Set the zero-based occurrence index for this issue.
Use this when the same segment tag appears multiple times in a message and you want to identify which occurrence is affected.
Sourcepub fn with_message_ref(self, message_ref: impl Into<String>) -> Self
pub fn with_message_ref(self, message_ref: impl Into<String>) -> Self
Set the message reference (UNH element 0) for this issue.
Use this to correlate an issue back to a specific message in a multi-message interchange.
Sourcepub fn with_segment_group(self, group: impl Into<Arc<str>>) -> Self
pub fn with_segment_group(self, group: impl Into<Arc<str>>) -> Self
Set the segment group (e.g. "SG6") in which this issue occurred.
Use this from group-aware rule functions that evaluate a sub-slice of a
crate::group::SegmentGroupIndexed tree so that consumers can identify
the exact group occurrence without re-reading the raw message.
Sourcepub fn with_context_entry(
self,
key: impl Into<String>,
value: impl Into<String>,
) -> Self
pub fn with_context_entry( self, key: impl Into<String>, value: impl Into<String>, ) -> Self
Insert a single key-value entry into the domain-specific context map.
Calling this multiple times accumulates entries; duplicate keys overwrite the previous value.
§Example
let issue = ValidationIssue::new(ValidationSeverity::Error, "BGM code invalid")
.with_rule_id("AHB-13001-BGM-M")
.with_context_entry("pid", "13001")
.with_context_entry("partner", "9900123456789");
assert_eq!(issue.context_get("pid"), Some("13001"));
assert_eq!(issue.context_get("partner"), Some("9900123456789"));Sourcepub fn with_context_entries<K, V, I>(self, entries: I) -> Self
pub fn with_context_entries<K, V, I>(self, entries: I) -> Self
Sourcepub fn context_get(&self, key: &str) -> Option<&str>
pub fn context_get(&self, key: &str) -> Option<&str>
Look up a value in the domain-specific context map.
Sourcepub fn severity_label(&self) -> &'static str
pub fn severity_label(&self) -> &'static str
Short label for the severity level, suitable for display.
Sourcepub fn error_code(&self) -> Option<&'static str>
pub fn error_code(&self) -> Option<&'static str>
Stable error code, if available.
Sourcepub fn segment_tag(&self) -> Option<&str>
pub fn segment_tag(&self) -> Option<&str>
Segment tag involved in this issue, if known.
Sourcepub fn element_index(&self) -> Option<u8>
pub fn element_index(&self) -> Option<u8>
Zero-based element index, if known.
Sourcepub fn component_index(&self) -> Option<u8>
pub fn component_index(&self) -> Option<u8>
Zero-based component index, if known.
Sourcepub fn segment_occurrence(&self) -> Option<u16>
pub fn segment_occurrence(&self) -> Option<u16>
Zero-based occurrence index among same-tag segments, if known.
Sourcepub fn message_ref(&self) -> Option<&str>
pub fn message_ref(&self) -> Option<&str>
Message reference (UNH element 0), if set.
Sourcepub fn suggestion(&self) -> Option<&str>
pub fn suggestion(&self) -> Option<&str>
Suggested remediation, if available.
Sourcepub fn segment_group(&self) -> Option<&str>
pub fn segment_group(&self) -> Option<&str>
Segment group (e.g. "SG6") in which the issue occurred, if known.
Trait Implementations§
Source§impl Clone for ValidationIssue
impl Clone for ValidationIssue
Source§fn clone(&self) -> ValidationIssue
fn clone(&self) -> ValidationIssue
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ValidationIssue
impl Debug for ValidationIssue
Source§impl<'de> Deserialize<'de> for ValidationIssue
impl<'de> Deserialize<'de> for ValidationIssue
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Display for ValidationIssue
impl Display for ValidationIssue
Source§impl Error for ValidationIssue
impl Error for ValidationIssue
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl PartialEq for ValidationIssue
impl PartialEq for ValidationIssue
Source§fn eq(&self, other: &ValidationIssue) -> bool
fn eq(&self, other: &ValidationIssue) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for ValidationIssue
impl Serialize for ValidationIssue
impl StructuralPartialEq for ValidationIssue
Auto Trait Implementations§
impl Freeze for ValidationIssue
impl RefUnwindSafe for ValidationIssue
impl Send for ValidationIssue
impl Sync for ValidationIssue
impl Unpin for ValidationIssue
impl UnsafeUnpin for ValidationIssue
impl UnwindSafe for ValidationIssue
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more