swift_mt_message/fields/
field33.rs1use super::swift_utils::{
2 format_swift_amount_for_currency, parse_amount_with_currency, parse_currency_non_commodity,
3};
4use crate::errors::ParseError;
5use crate::traits::SwiftField;
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
22pub struct Field33B {
23 pub currency: String,
25 pub amount: f64,
27}
28
29impl SwiftField for Field33B {
30 fn parse(input: &str) -> crate::Result<Self>
31 where
32 Self: Sized,
33 {
34 if input.len() < 4 {
36 return Err(ParseError::InvalidFormat {
38 message: format!(
39 "Field 33B must be at least 4 characters, found {}",
40 input.len()
41 ),
42 });
43 }
44
45 let currency = parse_currency_non_commodity(&input[0..3])?;
47
48 let amount_str = &input[3..];
50 if amount_str.is_empty() {
51 return Err(ParseError::InvalidFormat {
52 message: "Field 33B amount cannot be empty".to_string(),
53 });
54 }
55
56 let amount = parse_amount_with_currency(amount_str, ¤cy)?;
57
58 if amount <= 0.0 {
60 return Err(ParseError::InvalidFormat {
61 message: "Field 33B amount must be greater than zero".to_string(),
62 });
63 }
64
65 Ok(Field33B { currency, amount })
66 }
67
68 fn to_swift_string(&self) -> String {
69 format!(
70 ":33B:{}{}",
71 self.currency,
72 format_swift_amount_for_currency(self.amount, &self.currency)
73 )
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_field33b_valid() {
83 let field = Field33B::parse("USD1250,00").unwrap();
84 assert_eq!(field.currency, "USD");
85 assert_eq!(field.amount, 1250.00);
86 assert_eq!(field.to_swift_string(), ":33B:USD1250");
87
88 let field = Field33B::parse("EUR950,50").unwrap();
89 assert_eq!(field.currency, "EUR");
90 assert_eq!(field.amount, 950.50);
91
92 let field = Field33B::parse("JPY125000").unwrap();
93 assert_eq!(field.currency, "JPY");
94 assert_eq!(field.amount, 125000.0);
95 }
96
97 #[test]
98 fn test_field33b_invalid() {
99 assert!(Field33B::parse("12A100").is_err());
101 assert!(Field33B::parse("US100").is_err());
102
103 assert!(Field33B::parse("USD0").is_err());
105
106 assert!(Field33B::parse("USD-100").is_err());
108
109 assert!(Field33B::parse("USD").is_err());
111 }
112}