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
use crate::errors::SwiftValidationError;
use crate::fields::*;
use crate::parser::utils::*;
use serde::{Deserialize, Serialize};
/// **MT199: Free Format Message**
///
/// Free format communication between financial institutions regarding customer payments.
///
/// **Usage:** General payment inquiries, informal communication, status messages
/// **Category:** Category 1 (Customer Payments & Cheques)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub struct MT199 {
/// Sender's Reference (Field 20)
#[serde(rename = "20")]
pub field_20: Field20,
/// Related Reference (Field 21)
#[serde(rename = "21", skip_serializing_if = "Option::is_none")]
pub field_21: Option<Field21NoOption>,
/// Narrative (Field 79)
#[serde(rename = "79")]
pub field_79: Field79,
}
impl MT199 {
/// Parse message from Block 4 content
pub fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
let mut parser = crate::parser::MessageParser::new(block4, "199");
// Parse mandatory field 20
let field_20 = parser.parse_field::<Field20>("20")?;
// Parse optional field 21
let field_21 = parser.parse_optional_field::<Field21NoOption>("21")?;
// Parse mandatory field 79
let field_79 = parser.parse_field::<Field79>("79")?;
Ok(MT199 {
field_20,
field_21,
field_79,
})
}
/// Parse from generic SWIFT input (tries to detect blocks)
pub fn parse(input: &str) -> Result<Self, crate::errors::ParseError> {
let block4 = extract_block4(input)?;
Self::parse_from_block4(&block4)
}
// ========================================================================
// NETWORK VALIDATION RULES (SR 2025 MTn99)
// ========================================================================
/// Main validation method - validates all network rules
///
/// According to SR 2025 MTn99 specification:
/// "There are no network validated rules for this message type beyond the standard
/// field-specific rules."
///
/// Returns array of validation errors, respects stop_on_first_error flag.
///
/// ## Parameters
/// - `stop_on_first_error`: If true, returns immediately upon finding the first error
///
/// ## Returns
/// - Empty vector (MT199 has no network validation rules)
pub fn validate_network_rules(&self, _stop_on_first_error: bool) -> Vec<SwiftValidationError> {
// MT199 has no network validated rules according to SR 2025 specification
// All validation is performed at the field level during parsing
Vec::new()
}
/// Check if this is a reject message
pub fn is_reject_message(&self) -> bool {
self.field_79
.information
.first()
.map(|line| line.starts_with("/REJT/"))
.unwrap_or(false)
}
/// Check if this is a return message
pub fn is_return_message(&self) -> bool {
self.field_79
.information
.first()
.map(|line| line.starts_with("/RETN/"))
.unwrap_or(false)
}
}
impl crate::traits::SwiftMessageBody for MT199 {
fn message_type() -> &'static str {
"199"
}
fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
// Call the existing public method implementation
MT199::parse_from_block4(block4)
}
fn to_mt_string(&self) -> String {
// Call the existing public method implementation
let mut result = String::new();
append_field(&mut result, &self.field_20);
append_optional_field(&mut result, &self.field_21);
append_field(&mut result, &self.field_79);
finalize_mt_string(result, false)
}
fn validate_network_rules(&self, stop_on_first_error: bool) -> Vec<SwiftValidationError> {
// Call the existing public method implementation
MT199::validate_network_rules(self, stop_on_first_error)
}
}