1use crate::error::*;
21use regex::Regex;
22use serde::{Deserialize, Serialize};
23
24#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
26pub struct BranchAndFinancialInstitutionIdentification81 {
27 #[serde(rename = "FinInstnId")]
28 pub fin_instn_id: FinancialInstitutionIdentification231,
29}
30
31impl BranchAndFinancialInstitutionIdentification81 {
32 pub fn validate(&self) -> Result<(), ValidationError> {
33 self.fin_instn_id.validate()?;
34 Ok(())
35 }
36}
37
38#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
40pub struct CorrespondenceNotification11 {
41 #[serde(rename = "SndrNtfctnId")]
42 pub sndr_ntfctn_id: String,
43 #[serde(rename = "NtfctnTp")]
44 pub ntfctn_tp: NotificationType1Choice1,
45 #[serde(rename = "NtfctnNrrtv")]
46 pub ntfctn_nrrtv: Vec<String>,
47}
48
49impl CorrespondenceNotification11 {
50 pub fn validate(&self) -> Result<(), ValidationError> {
51 if self.sndr_ntfctn_id.chars().count() < 1 {
52 return Err(ValidationError::new(
53 1001,
54 "sndr_ntfctn_id is shorter than the minimum length of 1".to_string(),
55 ));
56 }
57 if self.sndr_ntfctn_id.chars().count() > 35 {
58 return Err(ValidationError::new(
59 1002,
60 "sndr_ntfctn_id exceeds the maximum length of 35".to_string(),
61 ));
62 }
63 let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
64 if !pattern.is_match(&self.sndr_ntfctn_id) {
65 return Err(ValidationError::new(
66 1005,
67 "sndr_ntfctn_id does not match the required pattern".to_string(),
68 ));
69 }
70 self.ntfctn_tp.validate()?;
71 for item in &self.ntfctn_nrrtv {
72 if item.chars().count() < 1 {
73 return Err(ValidationError::new(
74 1001,
75 "ntfctn_nrrtv is shorter than the minimum length of 1".to_string(),
76 ));
77 }
78 if item.chars().count() > 2000 {
79 return Err(ValidationError::new(
80 1002,
81 "ntfctn_nrrtv exceeds the maximum length of 2000".to_string(),
82 ));
83 }
84 let pattern = Regex::new(
85 "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
86 )
87 .unwrap();
88 if !pattern.is_match(&item) {
89 return Err(ValidationError::new(
90 1005,
91 "ntfctn_nrrtv does not match the required pattern".to_string(),
92 ));
93 }
94 }
95 Ok(())
96 }
97}
98
99#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
101pub struct FinancialInstitutionIdentification231 {
102 #[serde(rename = "BICFI")]
103 pub bicfi: String,
104}
105
106impl FinancialInstitutionIdentification231 {
107 pub fn validate(&self) -> Result<(), ValidationError> {
108 let pattern =
109 Regex::new("[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}").unwrap();
110 if !pattern.is_match(&self.bicfi) {
111 return Err(ValidationError::new(
112 1005,
113 "bicfi does not match the required pattern".to_string(),
114 ));
115 }
116 Ok(())
117 }
118}
119
120#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
122pub struct GroupHeader1291 {
123 #[serde(rename = "MsgId")]
124 pub msg_id: String,
125 #[serde(rename = "CreDtTm")]
126 pub cre_dt_tm: String,
127 #[serde(rename = "Sndr")]
128 pub sndr: Party50Choice1,
129 #[serde(rename = "Rcvr")]
130 pub rcvr: Party50Choice1,
131}
132
133impl GroupHeader1291 {
134 pub fn validate(&self) -> Result<(), ValidationError> {
135 if self.msg_id.chars().count() < 1 {
136 return Err(ValidationError::new(
137 1001,
138 "msg_id is shorter than the minimum length of 1".to_string(),
139 ));
140 }
141 if self.msg_id.chars().count() > 35 {
142 return Err(ValidationError::new(
143 1002,
144 "msg_id exceeds the maximum length of 35".to_string(),
145 ));
146 }
147 let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
148 if !pattern.is_match(&self.msg_id) {
149 return Err(ValidationError::new(
150 1005,
151 "msg_id does not match the required pattern".to_string(),
152 ));
153 }
154 let pattern = Regex::new(".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]").unwrap();
155 if !pattern.is_match(&self.cre_dt_tm) {
156 return Err(ValidationError::new(
157 1005,
158 "cre_dt_tm does not match the required pattern".to_string(),
159 ));
160 }
161 self.sndr.validate()?;
162 self.rcvr.validate()?;
163 Ok(())
164 }
165}
166
167#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
169pub struct NotificationOfCorrespondenceV01 {
170 #[serde(rename = "GrpHdr")]
171 pub grp_hdr: GroupHeader1291,
172 #[serde(rename = "NtfctnData")]
173 pub ntfctn_data: CorrespondenceNotification11,
174}
175
176impl NotificationOfCorrespondenceV01 {
177 pub fn validate(&self) -> Result<(), ValidationError> {
178 self.grp_hdr.validate()?;
179 self.ntfctn_data.validate()?;
180 Ok(())
181 }
182}
183
184#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
186pub struct NotificationType1Choice1 {
187 #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
188 pub cd: Option<String>,
189}
190
191impl NotificationType1Choice1 {
192 pub fn validate(&self) -> Result<(), ValidationError> {
193 if let Some(ref val) = self.cd {
194 if val.chars().count() < 1 {
195 return Err(ValidationError::new(
196 1001,
197 "cd is shorter than the minimum length of 1".to_string(),
198 ));
199 }
200 if val.chars().count() > 4 {
201 return Err(ValidationError::new(
202 1002,
203 "cd exceeds the maximum length of 4".to_string(),
204 ));
205 }
206 }
207 Ok(())
208 }
209}
210
211#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
213pub struct Party50Choice1 {
214 #[serde(rename = "Agt", skip_serializing_if = "Option::is_none")]
215 pub agt: Option<BranchAndFinancialInstitutionIdentification81>,
216}
217
218impl Party50Choice1 {
219 pub fn validate(&self) -> Result<(), ValidationError> {
220 if let Some(ref val) = self.agt {
221 val.validate()?
222 }
223 Ok(())
224 }
225}