mx20022_translate/mappings/error.rs
1//! Error and result types for MT↔MX translation.
2
3use thiserror::Error;
4
5/// Errors that can occur during translation between MT and MX messages.
6#[derive(Debug, Error)]
7pub enum TranslationError {
8 /// The message type is not supported by this translation layer.
9 #[error("unsupported message type: {0}")]
10 UnsupportedMessageType(String),
11
12 /// A field required for translation is absent from the source message.
13 #[error("missing required field: {field} for {context}")]
14 MissingField { field: String, context: String },
15
16 /// A field's value cannot be mapped to the target format.
17 #[error("invalid field value: {field}: {detail}")]
18 InvalidFieldValue { field: String, detail: String },
19
20 /// The source MT text could not be parsed.
21 #[error("MT parse error: {0}")]
22 MtParse(#[from] crate::mt::MtError),
23
24 /// The source MX XML could not be parsed.
25 #[error("MX parse error: {0}")]
26 MxParse(#[from] mx20022_parse::ParseError),
27
28 /// A model builder rejected its inputs.
29 #[error("builder error: {0}")]
30 Builder(#[from] mx20022_model::common::BuilderError),
31}
32
33// ---------------------------------------------------------------------------
34// TranslationWarning
35// ---------------------------------------------------------------------------
36
37/// A single field-level data-loss warning produced during translation.
38///
39/// Warnings indicate that a field was truncated, approximated, or could not
40/// be fully represented in the target format but did not prevent translation
41/// from completing.
42#[derive(Debug, Clone, PartialEq)]
43pub struct TranslationWarning {
44 /// The source or target field name, e.g. `":72:"` or `"CdtTrfTxInf.RmtInf"`.
45 pub field: String,
46 /// A human-readable description of what was lost or approximated.
47 pub message: String,
48}
49
50/// A collection of [`TranslationWarning`]s accumulated during a single
51/// translation call.
52#[derive(Debug, Clone, PartialEq, Default)]
53pub struct TranslationWarnings {
54 /// The warnings in the order they were recorded.
55 pub warnings: Vec<TranslationWarning>,
56}
57
58impl TranslationWarnings {
59 /// Append a new warning.
60 pub fn add(&mut self, field: impl Into<String>, message: impl Into<String>) {
61 self.warnings.push(TranslationWarning {
62 field: field.into(),
63 message: message.into(),
64 });
65 }
66
67 /// Returns `true` when no warnings have been recorded.
68 pub fn is_empty(&self) -> bool {
69 self.warnings.is_empty()
70 }
71}
72
73// ---------------------------------------------------------------------------
74// TranslationResult
75// ---------------------------------------------------------------------------
76
77/// The outcome of a successful translation.
78///
79/// `T` is the translated message type (`Document`, `String`, …).
80/// `warnings` contains any data-loss notes that did not prevent the
81/// translation from completing.
82#[derive(Debug)]
83pub struct TranslationResult<T: std::fmt::Debug> {
84 /// The translated message.
85 pub message: T,
86 /// Any warnings about data that was truncated, approximated, or lost.
87 pub warnings: TranslationWarnings,
88}