Skip to main content

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}