swift_mt_message/fields/
field20.rs1use super::swift_utils::{parse_max_length, parse_swift_chars};
2use crate::errors::ParseError;
3use crate::traits::SwiftField;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
19pub struct Field20 {
20 pub reference: String,
22}
23
24impl SwiftField for Field20 {
25 fn parse(input: &str) -> crate::Result<Self>
26 where
27 Self: Sized,
28 {
29 let reference = parse_max_length(input, 16, "Field 20 reference")?;
31
32 parse_swift_chars(&reference, "Field 20 reference")?;
34
35 if reference.starts_with('/') || reference.ends_with('/') {
37 return Err(ParseError::InvalidFormat {
38 message: "Field 20 reference cannot start or end with '/'".to_string(),
39 });
40 }
41
42 if reference.contains("//") {
44 return Err(ParseError::InvalidFormat {
45 message: "Field 20 reference cannot contain consecutive slashes '//'".to_string(),
46 });
47 }
48
49 Ok(Field20 { reference })
50 }
51
52 fn to_swift_string(&self) -> String {
53 format!(":20:{}", self.reference)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn test_field20_parse_valid() {
63 let field = Field20::parse("PAYMENT123456").unwrap();
64 assert_eq!(field.reference, "PAYMENT123456");
65
66 let field = Field20::parse("INV2024001234").unwrap();
67 assert_eq!(field.reference, "INV2024001234");
68
69 let field = Field20::parse("TXN20240719001").unwrap();
70 assert_eq!(field.reference, "TXN20240719001");
71 }
72
73 #[test]
74 fn test_field20_max_length() {
75 let field = Field20::parse("1234567890ABCDEF").unwrap();
77 assert_eq!(field.reference, "1234567890ABCDEF");
78
79 assert!(Field20::parse("1234567890ABCDEFG").is_err());
81 }
82
83 #[test]
84 fn test_field20_slash_validation() {
85 assert!(Field20::parse("/PAYMENT123").is_err());
87
88 assert!(Field20::parse("PAYMENT123/").is_err());
90
91 assert!(Field20::parse("PAY//MENT123").is_err());
93
94 let field = Field20::parse("PAY/MENT123").unwrap();
96 assert_eq!(field.reference, "PAY/MENT123");
97 }
98
99 #[test]
100 fn test_field20_to_swift_string() {
101 let field = Field20 {
102 reference: "PAYMENT123456".to_string(),
103 };
104 assert_eq!(field.to_swift_string(), ":20:PAYMENT123456");
105 }
106}