swift_mt_message/fields/
field19.rs

1//! **Field 19: Sum of Amounts**
2//!
3//! Sum of all individual transaction amounts in sequence transactions for reconciliation and validation.
4
5use super::swift_utils::parse_amount;
6use crate::traits::SwiftField;
7use serde::{Deserialize, Serialize};
8
9/// **Field 19: Sum of Amounts**
10///
11/// Sum of all individual transaction amounts in sequence for batch reconciliation.
12///
13/// **Format:** `17d` (up to 17 digits with decimal comma)
14/// **Constraints:** Must equal sum of all Field 32B amounts
15///
16/// **Example:**
17/// ```text
18/// :19:123456,78
19/// ```
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct Field19 {
22    /// Sum of transaction amounts (must match sum of Field 32B)
23    pub amount: f64,
24}
25
26impl SwiftField for Field19 {
27    fn parse(input: &str) -> crate::Result<Self>
28    where
29        Self: Sized,
30    {
31        let amount = parse_amount(input)?;
32
33        Ok(Field19 { amount })
34    }
35
36    fn to_swift_string(&self) -> String {
37        format!(":19:{}", format_swift_amount(self.amount))
38    }
39}
40
41/// Format amount for SWIFT output with comma as decimal separator
42fn format_swift_amount(amount: f64) -> String {
43    let formatted = format!("{:.2}", amount);
44    formatted.replace('.', ",")
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_field19_parse() {
53        let field = Field19::parse("123456.78").unwrap();
54        assert_eq!(field.amount, 123456.78);
55
56        let field = Field19::parse("123456,78").unwrap();
57        assert_eq!(field.amount, 123456.78);
58
59        let field = Field19::parse("1000").unwrap();
60        assert_eq!(field.amount, 1000.0);
61    }
62
63    #[test]
64    fn test_field19_to_swift_string() {
65        let field = Field19 { amount: 123456.78 };
66        assert_eq!(field.to_swift_string(), ":19:123456,78");
67
68        let field = Field19 { amount: 1000.0 };
69        assert_eq!(field.to_swift_string(), ":19:1000,00");
70    }
71
72    #[test]
73    fn test_field19_parse_invalid() {
74        assert!(Field19::parse("abc").is_err());
75        assert!(Field19::parse("").is_err());
76    }
77}