swift_mt_message/messages/mt935.rs
1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT935: Rate Change Advice
6///
7/// This message is used by a financial institution to advise another financial institution
8/// of a change in interest rates. This message is critical for managing interest
9/// rate exposure, updating pricing models, and ensuring accurate interest calculations
10/// across correspondent banking relationships and customer accounts.
11///
12/// ## Key Features
13/// - **Interest rate updates**: Notifying changes in deposit or lending rates
14/// - **Base rate changes**: Communicating central bank rate adjustments
15/// - **Account-specific rates**: Updating rates for specific customer accounts
16/// - **Product rate changes**: Modifying rates for specific banking products
17/// - **Regulatory compliance**: Meeting rate disclosure requirements
18/// - **Risk management**: Coordinating rate changes across institutions
19///
20/// ## Field Structure
21/// All fields follow the enhanced macro system with proper validation rules.
22/// The message supports repetitive rate change sequences for bulk updates.
23///
24/// ## Conditional Rules
25/// - **C1**: The repeating sequence of fields 23/25/30/37H must occur at least once and at most 10 times
26/// - **C2**: Either Field 23 or Field 25 must be present in each sequence, but not both
27#[serde_swift_fields]
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
29#[validation_rules(MT935_VALIDATION_RULES)]
30pub struct MT935 {
31 /// **Transaction Reference Number** - Field 20
32 ///
33 /// Unique sender's reference for this rate change advice.
34 /// Used for tracking and auditing rate change communications.
35 #[field("20", mandatory)]
36 pub field_20: GenericReferenceField,
37
38 /// **Rate Change Sequences** (Repetitive)
39 ///
40 /// Each sequence represents one rate change with either rate type
41 /// identification (Field 23) or account identification (Field 25),
42 /// along with the effective date and new rate.
43 #[field("RATE_CHANGES", repetitive)]
44 pub rate_changes: Vec<MT935RateChange>,
45
46 /// **Sender to Receiver Information** - Field 72 (Optional)
47 ///
48 /// Additional information about the rate changes.
49 /// Can include structured text or narrative details.
50 #[field("72", optional)]
51 pub field_72: Option<GenericMultiLineTextField<6, 35>>,
52}
53
54/// # MT935 Rate Change Sequence
55///
56/// Represents a single rate change within an MT935 message.
57/// Each sequence must have either Field 23 (rate type) OR Field 25 (account), but not both.
58/// Enhanced with SwiftMessage derive for automatic parsing and validation as a sub-message structure.
59#[serde_swift_fields]
60#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
61#[validation_rules(MT935_RATE_CHANGE_VALIDATION_RULES)]
62pub struct MT935RateChange {
63 /// **Further Identification** - Field 23 (Conditional C2)
64 ///
65 /// Identifies the type of rate being changed (BASE, CALL, COMMERCIAL, etc.)
66 /// Function codes: BASE, CALL, COMMERCIAL, CURRENT, DEPOSIT, NOTICE, PRIME
67 #[field("23", optional)]
68 pub field_23: Option<Field23>,
69
70 /// **Account Identification** - Field 25 (Conditional C2)
71 ///
72 /// Identifies specific account for account-specific rate changes.
73 /// Alternative to Field 23 when rate applies to individual account.
74 #[field("25", optional)]
75 pub field_25: Option<GenericTextField>,
76
77 /// **Effective Date of New Rate** - Field 30 (Mandatory)
78 ///
79 /// When the new rate becomes effective (YYMMDD format).
80 /// Must be a valid calendar date.
81 #[field("30", mandatory)]
82 pub field_30: GenericTextField,
83
84 /// **New Interest Rate** - Field 37H (Mandatory)
85 ///
86 /// The new interest rate value with C/D indicator.
87 /// Indicator: 'C' for credit rate, 'D' for debit rate.
88 #[field("37H", mandatory)]
89 pub field_37h: Field37H,
90}
91
92/// Enhanced validation rules for MT935
93const MT935_VALIDATION_RULES: &str = r#"{
94 "rules": [
95 {
96 "id": "C1",
97 "description": "Rate change sequences must occur 1-10 times",
98 "condition": {
99 "and": [
100 {">=": [{"length": {"var": "rate_changes"}}, 1]},
101 {"<=": [{"length": {"var": "rate_changes"}}, 10]}
102 ]
103 }
104 },
105 {
106 "id": "REF_FORMAT",
107 "description": "Transaction reference must not have invalid slash patterns",
108 "condition": {
109 "and": [
110 {"!": {"startsWith": [{"var": "field_20.value"}, "/"]}},
111 {"!": {"endsWith": [{"var": "field_20.value"}, "/"]}},
112 {"!": {"includes": [{"var": "field_20.value"}, "//"]}}
113 ]
114 }
115 },
116 {
117 "id": "REQUIRED_FIELDS",
118 "description": "All mandatory fields must be present and non-empty",
119 "condition": {
120 "!=": [{"var": "field_20.value"}, ""]
121 }
122 }
123 ]
124}"#;
125
126/// Validation rules specific to MT935 rate change sequences
127const MT935_RATE_CHANGE_VALIDATION_RULES: &str = r#"{
128 "rules": [
129 {
130 "id": "C2",
131 "description": "Either Field 23 or Field 25 must be present, but not both",
132 "condition": {
133 "or": [
134 {
135 "and": [
136 {"var": "field_23.is_some"},
137 {"var": "field_25.is_none"}
138 ]
139 },
140 {
141 "and": [
142 {"var": "field_23.is_none"},
143 {"var": "field_25.is_some"}
144 ]
145 }
146 ]
147 }
148 },
149 {
150 "id": "REQUIRED_SEQUENCE_FIELDS",
151 "description": "Effective date and new rate must be present and non-empty",
152 "condition": {
153 "and": [
154 {"!=": [{"var": "field_30.value"}, ""]},
155 {"var": "field_37h.is_valid"}
156 ]
157 }
158 }
159 ]
160}"#;