swift_mt_message/fields/
field56c.rs1use crate::{SwiftField, ValidationResult};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
94pub struct Field56C {
95 pub account_number: String,
97}
98
99impl Field56C {
100 pub fn new(account_number: impl Into<String>) -> Result<Self, crate::ParseError> {
102 let account_number = account_number.into().trim().to_string();
103
104 if account_number.is_empty() {
106 return Err(crate::ParseError::InvalidFieldFormat {
107 field_tag: "56C".to_string(),
108 message: "Account number cannot be empty".to_string(),
109 });
110 }
111
112 if account_number.len() > 34 {
113 return Err(crate::ParseError::InvalidFieldFormat {
114 field_tag: "56C".to_string(),
115 message: "Account number cannot exceed 34 characters".to_string(),
116 });
117 }
118
119 if !account_number
120 .chars()
121 .all(|c| c.is_ascii() && !c.is_control())
122 {
123 return Err(crate::ParseError::InvalidFieldFormat {
124 field_tag: "56C".to_string(),
125 message: "Account number contains invalid characters".to_string(),
126 });
127 }
128
129 Ok(Field56C { account_number })
130 }
131
132 pub fn account_number(&self) -> &str {
134 &self.account_number
135 }
136
137 pub fn description(&self) -> String {
139 format!(
140 "Intermediary Institution (Account: {})",
141 self.account_number
142 )
143 }
144}
145
146impl SwiftField for Field56C {
147 fn parse(content: &str) -> crate::Result<Self> {
148 let content = content.trim();
149 if content.is_empty() {
150 return Err(crate::ParseError::InvalidFieldFormat {
151 field_tag: "56C".to_string(),
152 message: "Field content cannot be empty".to_string(),
153 });
154 }
155
156 let content = if let Some(stripped) = content.strip_prefix(":56C:") {
157 stripped
158 } else if let Some(stripped) = content.strip_prefix("56C:") {
159 stripped
160 } else {
161 content
162 };
163
164 let account_number = if let Some(stripped) = content.strip_prefix('/') {
166 stripped
167 } else {
168 content
169 };
170
171 if account_number.is_empty() {
172 return Err(crate::ParseError::InvalidFieldFormat {
173 field_tag: "56C".to_string(),
174 message: "Account number is required".to_string(),
175 });
176 }
177
178 Field56C::new(account_number)
179 }
180
181 fn to_swift_string(&self) -> String {
182 format!(":56C:/{}", self.account_number)
183 }
184
185 fn validate(&self) -> ValidationResult {
186 ValidationResult {
188 is_valid: true,
189 errors: Vec::new(),
190 warnings: Vec::new(),
191 }
192 }
193
194 fn format_spec() -> &'static str {
195 "/34x"
196 }
197}
198
199impl std::fmt::Display for Field56C {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 write!(f, "Account: {}", self.account_number)
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use super::*;
208
209 #[test]
210 fn test_field56c_creation() {
211 let field = Field56C::new("INTERMEDIARYACCT123456").unwrap();
212 assert_eq!(field.account_number(), "INTERMEDIARYACCT123456");
213 }
214
215 #[test]
216 fn test_field56c_parse() {
217 let field = Field56C::parse("/INTERMEDIARYACCT123456").unwrap();
218 assert_eq!(field.account_number(), "INTERMEDIARYACCT123456");
219 }
220
221 #[test]
222 fn test_field56c_parse_without_slash() {
223 let field = Field56C::parse("INTERMEDIARYACCT123456").unwrap();
224 assert_eq!(field.account_number(), "INTERMEDIARYACCT123456");
225 }
226
227 #[test]
228 fn test_field56c_parse_with_tag() {
229 let field = Field56C::parse(":56C:/INTERMEDIARYACCT123456").unwrap();
230 assert_eq!(field.account_number(), "INTERMEDIARYACCT123456");
231 }
232
233 #[test]
234 fn test_field56c_to_swift_string() {
235 let field = Field56C::new("INTERMEDIARYACCT123456").unwrap();
236 assert_eq!(field.to_swift_string(), ":56C:/INTERMEDIARYACCT123456");
237 }
238
239 #[test]
240 fn test_field56c_display() {
241 let field = Field56C::new("INTERMEDIARYACCT123456").unwrap();
242 assert_eq!(format!("{}", field), "Account: INTERMEDIARYACCT123456");
243 }
244
245 #[test]
246 fn test_field56c_description() {
247 let field = Field56C::new("INTERMEDIARYACCT123456").unwrap();
248 assert_eq!(
249 field.description(),
250 "Intermediary Institution (Account: INTERMEDIARYACCT123456)"
251 );
252 }
253
254 #[test]
255 fn test_field56c_validation_empty_account() {
256 let result = Field56C::new("");
257 assert!(result.is_err());
258 assert!(result.unwrap_err().to_string().contains("cannot be empty"));
259 }
260
261 #[test]
262 fn test_field56c_validation_account_too_long() {
263 let account = "A".repeat(35); let result = Field56C::new(account);
265 assert!(result.is_err());
266 assert!(
267 result
268 .unwrap_err()
269 .to_string()
270 .contains("cannot exceed 34 characters")
271 );
272 }
273
274 #[test]
275 fn test_field56c_validation_invalid_characters() {
276 let result = Field56C::new("ACCOUNT\x00ID"); assert!(result.is_err());
278 assert!(
279 result
280 .unwrap_err()
281 .to_string()
282 .contains("invalid characters")
283 );
284 }
285
286 #[test]
287 fn test_field56c_validate() {
288 let field = Field56C::new("INTERMEDIARYACCT123456").unwrap();
289 let validation = field.validate();
290 assert!(validation.is_valid);
291 assert!(validation.errors.is_empty());
292 }
293}