swift_mt_message/messages/
mt900.rs1use crate::errors::SwiftValidationError;
2use crate::fields::*;
3use crate::parser::utils::*;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
13pub struct MT900 {
14 #[serde(rename = "20")]
16 pub field_20: Field20,
17
18 #[serde(rename = "21")]
20 pub field_21: Field21NoOption,
21
22 #[serde(rename = "25")]
24 pub field_25: Field25AccountIdentification,
25
26 #[serde(rename = "13D")]
28 pub field_13d: Option<Field13D>,
29
30 #[serde(rename = "32A")]
32 pub field_32a: Field32A,
33
34 #[serde(flatten)]
36 pub field_52: Option<Field52OrderingInstitution>,
37
38 #[serde(rename = "72")]
40 pub field_72: Option<Field72>,
41}
42
43impl MT900 {
44 pub fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
46 let mut parser = crate::parser::MessageParser::new(block4, "900");
47
48 let field_20 = parser.parse_field::<Field20>("20")?;
50 let field_21 = parser.parse_field::<Field21NoOption>("21")?;
51 let field_25 = parser.parse_field::<Field25AccountIdentification>("25")?;
52
53 let field_13d = parser.parse_optional_field::<Field13D>("13D")?;
55
56 let field_32a = parser.parse_field::<Field32A>("32A")?;
58
59 let field_52 = parser.parse_optional_variant_field::<Field52OrderingInstitution>("52")?;
61 let field_72 = parser.parse_optional_field::<Field72>("72")?;
62
63 verify_parser_complete(&parser)?;
65
66 Ok(Self {
67 field_20,
68 field_21,
69 field_25,
70 field_13d,
71 field_32a,
72 field_52,
73 field_72,
74 })
75 }
76
77 pub fn parse(input: &str) -> Result<Self, crate::errors::ParseError> {
79 let block4 = extract_block4(input)?;
80 Self::parse_from_block4(&block4)
81 }
82
83 pub fn to_mt_string(&self) -> String {
85 let mut result = String::new();
86
87 append_field(&mut result, &self.field_20);
88 append_field(&mut result, &self.field_21);
89 append_field(&mut result, &self.field_25);
90 append_optional_field(&mut result, &self.field_13d);
91 append_field(&mut result, &self.field_32a);
92 append_optional_field(&mut result, &self.field_52);
93 append_optional_field(&mut result, &self.field_72);
94
95 finalize_mt_string(result, false)
96 }
97
98 pub fn validate_network_rules(&self, _stop_on_first_error: bool) -> Vec<SwiftValidationError> {
109 Vec::new()
111 }
112}
113
114impl crate::traits::SwiftMessageBody for MT900 {
115 fn message_type() -> &'static str {
116 "900"
117 }
118
119 fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
120 MT900::parse_from_block4(block4)
122 }
123
124 fn to_mt_string(&self) -> String {
125 MT900::to_mt_string(self)
127 }
128
129 fn validate_network_rules(&self, stop_on_first_error: bool) -> Vec<SwiftValidationError> {
130 MT900::validate_network_rules(self, stop_on_first_error)
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn test_mt900_parse() {
141 let mt900_text = r#":20:20240719001
142:21:REF20240719001
143:25:12345678901234567890
144:32A:240719USD1000,00
145-"#;
146 let result = MT900::parse_from_block4(mt900_text);
147 assert!(result.is_ok());
148 let mt900 = result.unwrap();
149 assert_eq!(mt900.field_20.reference, "20240719001");
150 assert_eq!(mt900.field_21.reference, "REF20240719001");
151 }
152
153 #[test]
154 fn test_mt900_network_validation() {
155 let mt900_text = r#":20:20240719001
156:21:REF20240719001
157:25:12345678901234567890
158:32A:240719USD1000,00
159-"#;
160 let mt900 = MT900::parse_from_block4(mt900_text).unwrap();
161
162 let errors = mt900.validate_network_rules(false);
164 assert!(errors.is_empty(), "MT900 should have no validation errors");
165
166 let errors = mt900.validate_network_rules(true);
168 assert!(
169 errors.is_empty(),
170 "MT900 should have no validation errors with stop_on_first_error"
171 );
172 }
173
174 #[test]
175 fn test_mt900_trait_validate_network_rules() {
176 use crate::traits::SwiftMessageBody;
177
178 let mt900_text = r#":20:20240719001
179:21:REF20240719001
180:25:12345678901234567890
181:32A:240719USD1000,00
182-"#;
183 let mt900 = MT900::parse_from_block4(mt900_text).unwrap();
184
185 let errors = <MT900 as SwiftMessageBody>::validate_network_rules(&mt900, false);
187 assert!(
188 errors.is_empty(),
189 "Trait implementation should return empty vector"
190 );
191 }
192}