swift_mt_message/messages/
mt299.rs

1use crate::errors::{ParseError, SwiftValidationError};
2use crate::fields::*;
3use crate::parser::MessageParser;
4use crate::parser::utils::*;
5use serde::{Deserialize, Serialize};
6
7/// **MT299: Free Format Message**
8///
9/// Free-format text message for interbank communication.
10///
11/// **Usage:** General correspondence, operational messages
12/// **Category:** Category 2 (Financial Institution Transfers)
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
14pub struct MT299 {
15    /// Transaction Reference (Field 20)
16    #[serde(rename = "20")]
17    pub field_20: Field20,
18
19    /// Related Reference (Field 21)
20    #[serde(rename = "21", skip_serializing_if = "Option::is_none")]
21    pub field_21: Option<Field21NoOption>,
22
23    /// Narrative (Field 79)
24    #[serde(rename = "79")]
25    pub field_79: Field79,
26}
27
28impl MT299 {
29    /// Parse MT299 from a raw SWIFT message string
30    pub fn parse_from_block4(block4: &str) -> Result<Self, ParseError> {
31        let mut parser = MessageParser::new(block4, "299");
32
33        // Parse mandatory Field 20
34        let field_20 = parser.parse_field::<Field20>("20")?;
35
36        // Parse optional Field 21
37        let field_21 = parser.parse_optional_field::<Field21NoOption>("21")?;
38
39        // Parse mandatory Field 79
40        let field_79 = parser.parse_field::<Field79>("79")?;
41
42        Ok(MT299 {
43            field_20,
44            field_21,
45            field_79,
46        })
47    }
48
49    // ========================================================================
50    // NETWORK VALIDATION RULES (SR 2025 MTn99)
51    // ========================================================================
52
53    /// Main validation method - validates all network rules
54    ///
55    /// **Note**: According to SR 2025 specifications, MT n99 messages have no
56    /// network validated rules beyond standard field-specific rules, which are
57    /// already enforced during parsing. This method always returns an empty vector.
58    ///
59    /// Returns empty vector as there are no network validation rules for MT299
60    pub fn validate_network_rules(&self, _stop_on_first_error: bool) -> Vec<SwiftValidationError> {
61        Vec::new()
62    }
63}
64
65impl crate::traits::SwiftMessageBody for MT299 {
66    fn message_type() -> &'static str {
67        "299"
68    }
69
70    fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
71        Self::parse_from_block4(block4)
72    }
73
74    fn to_mt_string(&self) -> String {
75        let mut result = String::new();
76
77        append_field(&mut result, &self.field_20);
78        append_optional_field(&mut result, &self.field_21);
79        append_field(&mut result, &self.field_79);
80
81        finalize_mt_string(result, false)
82    }
83
84    fn validate_network_rules(&self, stop_on_first_error: bool) -> Vec<SwiftValidationError> {
85        // Call the existing public method implementation
86        MT299::validate_network_rules(self, stop_on_first_error)
87    }
88}