Skip to main content

ValidationIssue

Struct ValidationIssue 

Source
#[non_exhaustive]
pub struct ValidationIssue {
Show 14 fields pub error_code: Option<&'static str>, pub severity: ValidationSeverity, pub message: String, pub offset: Option<usize>, pub span: Option<Span>, 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 discriminator

Example: "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
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional 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: ValidationSeverity

The severity of this issue.

§message: String

The error or warning message.

§offset: Option<usize>

Byte offset in the source (if available).

For precise source-range highlighting (e.g. in miette diagnostics or Language Server Protocol Range values), prefer span which carries both start and end. offset is kept for backwards compatibility and is always equal to span.start when both are set.

§span: Option<Span>

Half-open byte range of the relevant segment or element in the source.

Provides precise source-range information for diagnostics and editor tooling. Use with_span to set this from a Span obtained from a parsed crate::Segment. Setting span automatically populates offset with span.start for backwards compatibility.

§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

Source

pub fn new(severity: ValidationSeverity, message: impl Into<String>) -> Self

Create a new validation issue.

Source

pub fn with_error_code(self, code: &'static str) -> Self

Set stable error code metadata.

Source

pub fn with_offset(self, offset: usize) -> Self

Set the byte offset for this issue.

Source

pub fn with_span(self, span: Span) -> Self

Set the full byte-range span for this issue.

Also populates offset with span.start so that existing code that only reads offset continues to work.

Use this in preference to with_offset when you have access to the source Span from a parsed crate::Segment — the full range enables precise source-range highlighting in miette diagnostics and Language Server Protocol tooling.

§Example
let span = Span::new(42, 57);
let issue = ValidationIssue::new(ValidationSeverity::Error, "BGM code missing")
    .with_span(span);
assert_eq!(issue.offset, Some(42));
assert_eq!(issue.span, Some(span));
Source

pub fn with_segment(self, tag: impl Into<String>) -> Self

Set the segment tag for this issue.

Source

pub fn with_rule_id(self, rule_id: impl Into<String>) -> Self

Set the profile/MIG rule identifier for this issue.

Source

pub fn with_element_index(self, element_index: u8) -> Self

Set the element index (0-based) for this issue.

Source

pub fn with_component_index(self, component_index: u8) -> Self

Set the component index (0-based) for this issue.

Source

pub fn with_suggestion(self, suggestion: impl Into<String>) -> Self

Set a suggestion for resolving this issue.

Source

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.

Source

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.

Source

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.

Source

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"));
Source

pub fn with_context_entries<K, V, I>(self, entries: I) -> Self
where K: Into<String>, V: Into<String>, I: IntoIterator<Item = (K, V)>,

Extend the domain-specific context map from an iterator of (key, value) pairs.

§Example
let meta = [("pid", "13001"), ("partner", "9900123456789")];
let issue = ValidationIssue::new(ValidationSeverity::Error, "test")
    .with_context_entries(meta);

assert_eq!(issue.context_get("pid"), Some("13001"));
Source

pub fn context_get(&self, key: &str) -> Option<&str>

Look up a value in the domain-specific context map.

Source

pub fn severity_label(&self) -> &'static str

Short label for the severity level, suitable for display.

Source

pub fn error_code(&self) -> Option<&'static str>

Stable error code, if available.

Source

pub fn offset(&self) -> Option<usize>

Byte offset in the source, if available.

Source

pub fn span(&self) -> Option<Span>

Half-open byte range of the relevant source region, if available.

Source

pub fn segment_tag(&self) -> Option<&str>

Segment tag involved in this issue, if known.

Source

pub fn rule_id(&self) -> Option<&str>

Profile/MIG rule identifier, if applicable.

Source

pub fn element_index(&self) -> Option<u8>

Zero-based element index, if known.

Source

pub fn component_index(&self) -> Option<u8>

Zero-based component index, if known.

Source

pub fn segment_occurrence(&self) -> Option<u16>

Zero-based occurrence index among same-tag segments, if known.

Source

pub fn message_ref(&self) -> Option<&str>

Message reference (UNH element 0), if set.

Source

pub fn suggestion(&self) -> Option<&str>

Suggested remediation, if available.

Source

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

Source§

fn clone(&self) -> ValidationIssue

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ValidationIssue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ValidationIssue

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for ValidationIssue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ValidationIssue

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl Extend<ValidationIssue> for ValidationReport

Source§

fn extend<I: IntoIterator<Item = ValidationIssue>>(&mut self, iter: I)

Push each issue into the appropriate severity bucket.

This enables ergonomic batch collection:

use edifact_rs::{ValidationReport, ValidationIssue, ValidationSeverity};

let issues = vec![
    ValidationIssue::new(ValidationSeverity::Error, "bad segment"),
    ValidationIssue::new(ValidationSeverity::Warning, "optional field missing"),
    ValidationIssue::new(ValidationSeverity::Info, "advisory note"),
];
let mut report = ValidationReport::default();
report.extend(issues);
assert_eq!(report.errors().len(), 1);
assert_eq!(report.warnings().len(), 1);
assert_eq!(report.infos().len(), 1);
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl FromIterator<ValidationIssue> for ValidationReport

Source§

fn from_iter<I: IntoIterator<Item = ValidationIssue>>(iter: I) -> Self

Creates a value from an iterator. Read more
Source§

impl PartialEq for ValidationIssue

Source§

fn eq(&self, other: &ValidationIssue) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for ValidationIssue

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ValidationIssue

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<D> OwoColorize for D

Source§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
Source§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
Source§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
Source§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
Source§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
Source§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
Source§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
Source§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
Source§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
Source§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
Source§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
Source§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
Source§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
Source§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
Source§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
Source§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
Source§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
Source§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
Source§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
Source§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
Source§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
Source§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
Source§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
Source§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
Source§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
Source§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
Source§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
Source§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
Source§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
Source§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
Source§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
Source§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
Source§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
Source§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
Source§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
Source§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
Source§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
Source§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
Source§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
Source§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
Source§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
Source§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
Source§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
Source§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
Source§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
Source§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
Source§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
Source§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
Source§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
Source§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
Source§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
Source§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
Source§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
Source§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.