mx_message/document/
camt_106_001_02_mc.rs

1// Plasmatic MX Message Parsing Library
2// https://github.com/GoPlasmatic/MXMessage
3//
4// Copyright (c) 2025 Plasmatic
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9//     http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
17// You may obtain a copy of this library at
18// https://github.com/GoPlasmatic/MXMessage
19
20use crate::error::*;
21use regex::Regex;
22use serde::{Deserialize, Serialize};
23
24// AccountIdentification4Choice1: Unique identification of an account, as assigned by the account servicer, using an identification scheme.
25#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
26pub struct AccountIdentification4Choice1 {
27    #[serde(rename = "IBAN", skip_serializing_if = "Option::is_none")]
28    pub iban: Option<String>,
29    #[serde(rename = "Othr", skip_serializing_if = "Option::is_none")]
30    pub othr: Option<GenericAccountIdentification11>,
31}
32
33impl AccountIdentification4Choice1 {
34    pub fn validate(&self) -> Result<(), ValidationError> {
35        if let Some(ref val) = self.iban {
36            let pattern = Regex::new("[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}").unwrap();
37            if !pattern.is_match(val) {
38                return Err(ValidationError::new(
39                    1005,
40                    "iban does not match the required pattern".to_string(),
41                ));
42            }
43        }
44        if let Some(ref val) = self.othr {
45            val.validate()?
46        }
47        Ok(())
48    }
49}
50
51// AccountSchemeName1Choice1: Name of the identification scheme, in a free text form.
52#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
53pub struct AccountSchemeName1Choice1 {
54    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
55    pub cd: Option<String>,
56    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
57    pub prtry: Option<String>,
58}
59
60impl AccountSchemeName1Choice1 {
61    pub fn validate(&self) -> Result<(), ValidationError> {
62        if let Some(ref val) = self.cd {
63            if val.chars().count() < 1 {
64                return Err(ValidationError::new(
65                    1001,
66                    "cd is shorter than the minimum length of 1".to_string(),
67                ));
68            }
69            if val.chars().count() > 4 {
70                return Err(ValidationError::new(
71                    1002,
72                    "cd exceeds the maximum length of 4".to_string(),
73                ));
74            }
75        }
76        if let Some(ref val) = self.prtry {
77            if val.chars().count() < 1 {
78                return Err(ValidationError::new(
79                    1001,
80                    "prtry is shorter than the minimum length of 1".to_string(),
81                ));
82            }
83            if val.chars().count() > 35 {
84                return Err(ValidationError::new(
85                    1002,
86                    "prtry exceeds the maximum length of 35".to_string(),
87                ));
88            }
89            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
90            if !pattern.is_match(val) {
91                return Err(ValidationError::new(
92                    1005,
93                    "prtry does not match the required pattern".to_string(),
94                ));
95            }
96        }
97        Ok(())
98    }
99}
100
101// BranchAndFinancialInstitutionIdentification81: Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
102#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
103pub struct BranchAndFinancialInstitutionIdentification81 {
104    #[serde(rename = "FinInstnId")]
105    pub fin_instn_id: FinancialInstitutionIdentification231,
106}
107
108impl BranchAndFinancialInstitutionIdentification81 {
109    pub fn validate(&self) -> Result<(), ValidationError> {
110        self.fin_instn_id.validate()?;
111        Ok(())
112    }
113}
114
115// CBPRAmount: CBPR_Amount
116#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
117pub struct CBPRAmount {
118    #[serde(rename = "@Ccy")]
119    pub ccy: String,
120    #[serde(rename = "$value")]
121    pub value: f64,
122}
123
124impl CBPRAmount {
125    pub fn validate(&self) -> Result<(), ValidationError> {
126        Ok(())
127    }
128}
129
130// CashAccount401: Specifies an alternate assumed name for the identification of the account.
131#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
132pub struct CashAccount401 {
133    #[serde(rename = "Id")]
134    pub id: AccountIdentification4Choice1,
135    #[serde(rename = "Tp", skip_serializing_if = "Option::is_none")]
136    pub tp: Option<CashAccountType2Choice1>,
137    #[serde(rename = "Ccy", skip_serializing_if = "Option::is_none")]
138    pub ccy: Option<String>,
139    #[serde(rename = "Nm", skip_serializing_if = "Option::is_none")]
140    pub nm: Option<String>,
141    #[serde(rename = "Prxy", skip_serializing_if = "Option::is_none")]
142    pub prxy: Option<ProxyAccountIdentification11>,
143}
144
145impl CashAccount401 {
146    pub fn validate(&self) -> Result<(), ValidationError> {
147        self.id.validate()?;
148        if let Some(ref val) = self.tp {
149            val.validate()?
150        }
151        if let Some(ref val) = self.ccy {
152            let pattern = Regex::new("[A-Z]{3,3}").unwrap();
153            if !pattern.is_match(val) {
154                return Err(ValidationError::new(
155                    1005,
156                    "ccy does not match the required pattern".to_string(),
157                ));
158            }
159        }
160        if let Some(ref val) = self.nm {
161            if val.chars().count() < 1 {
162                return Err(ValidationError::new(
163                    1001,
164                    "nm is shorter than the minimum length of 1".to_string(),
165                ));
166            }
167            if val.chars().count() > 70 {
168                return Err(ValidationError::new(
169                    1002,
170                    "nm exceeds the maximum length of 70".to_string(),
171                ));
172            }
173            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
174            if !pattern.is_match(val) {
175                return Err(ValidationError::new(
176                    1005,
177                    "nm does not match the required pattern".to_string(),
178                ));
179            }
180        }
181        if let Some(ref val) = self.prxy {
182            val.validate()?
183        }
184        Ok(())
185    }
186}
187
188// CashAccountType2Choice1: Nature or use of the account in a proprietary form.
189#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
190pub struct CashAccountType2Choice1 {
191    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
192    pub cd: Option<String>,
193    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
194    pub prtry: Option<String>,
195}
196
197impl CashAccountType2Choice1 {
198    pub fn validate(&self) -> Result<(), ValidationError> {
199        if let Some(ref val) = self.cd {
200            if val.chars().count() < 1 {
201                return Err(ValidationError::new(
202                    1001,
203                    "cd is shorter than the minimum length of 1".to_string(),
204                ));
205            }
206            if val.chars().count() > 4 {
207                return Err(ValidationError::new(
208                    1002,
209                    "cd exceeds the maximum length of 4".to_string(),
210                ));
211            }
212        }
213        if let Some(ref val) = self.prtry {
214            if val.chars().count() < 1 {
215                return Err(ValidationError::new(
216                    1001,
217                    "prtry is shorter than the minimum length of 1".to_string(),
218                ));
219            }
220            if val.chars().count() > 35 {
221                return Err(ValidationError::new(
222                    1002,
223                    "prtry exceeds the maximum length of 35".to_string(),
224                ));
225            }
226            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
227            if !pattern.is_match(val) {
228                return Err(ValidationError::new(
229                    1005,
230                    "prtry does not match the required pattern".to_string(),
231                ));
232            }
233        }
234        Ok(())
235    }
236}
237
238// ChargeType3Choice1: Charge type, in a coded form.
239#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
240pub struct ChargeType3Choice1 {
241    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
242    pub cd: Option<String>,
243}
244
245impl ChargeType3Choice1 {
246    pub fn validate(&self) -> Result<(), ValidationError> {
247        if let Some(ref val) = self.cd {
248            if val.chars().count() < 1 {
249                return Err(ValidationError::new(
250                    1001,
251                    "cd is shorter than the minimum length of 1".to_string(),
252                ));
253            }
254            if val.chars().count() > 4 {
255                return Err(ValidationError::new(
256                    1002,
257                    "cd exceeds the maximum length of 4".to_string(),
258                ));
259            }
260        }
261        Ok(())
262    }
263}
264
265// Charges3Choice1: Charges broken down per payment transaction.
266#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
267pub struct Charges3Choice1 {
268    #[serde(rename = "PerTx", skip_serializing_if = "Option::is_none")]
269    pub per_tx: Option<ChargesPerTransaction31>,
270}
271
272impl Charges3Choice1 {
273    pub fn validate(&self) -> Result<(), ValidationError> {
274        if let Some(ref val) = self.per_tx {
275            val.validate()?
276        }
277        Ok(())
278    }
279}
280
281// ChargesBreakdown11: Specifies the type of charge.
282#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
283pub struct ChargesBreakdown11 {
284    #[serde(rename = "Amt")]
285    pub amt: CBPRAmount,
286    #[serde(rename = "CdtDbtInd")]
287    pub cdt_dbt_ind: CreditDebitCode1,
288    #[serde(rename = "Tp")]
289    pub tp: ChargeType3Choice1,
290}
291
292impl ChargesBreakdown11 {
293    pub fn validate(&self) -> Result<(), ValidationError> {
294        self.amt.validate()?;
295        self.cdt_dbt_ind.validate()?;
296        self.tp.validate()?;
297        Ok(())
298    }
299}
300
301// ChargesPaymentRequestV02: Provides information on the charges to be paid by the charge bearer(s) related to the processing of the underlying transaction.
302#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
303pub struct ChargesPaymentRequestV02 {
304    #[serde(rename = "GrpHdr")]
305    pub grp_hdr: GroupHeader1151,
306    #[serde(rename = "Chrgs")]
307    pub chrgs: Charges3Choice1,
308}
309
310impl ChargesPaymentRequestV02 {
311    pub fn validate(&self) -> Result<(), ValidationError> {
312        self.grp_hdr.validate()?;
313        self.chrgs.validate()?;
314        Ok(())
315    }
316}
317
318// ChargesPerTransaction31: Itemised charges record per transaction.
319#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
320pub struct ChargesPerTransaction31 {
321    #[serde(rename = "ChrgsId")]
322    pub chrgs_id: String,
323    #[serde(rename = "Rcrd")]
324    pub rcrd: Vec<ChargesPerTransactionRecord31>,
325}
326
327impl ChargesPerTransaction31 {
328    pub fn validate(&self) -> Result<(), ValidationError> {
329        if self.chrgs_id.chars().count() < 1 {
330            return Err(ValidationError::new(
331                1001,
332                "chrgs_id is shorter than the minimum length of 1".to_string(),
333            ));
334        }
335        if self.chrgs_id.chars().count() > 16 {
336            return Err(ValidationError::new(
337                1002,
338                "chrgs_id exceeds the maximum length of 16".to_string(),
339            ));
340        }
341        let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
342        if !pattern.is_match(&self.chrgs_id) {
343            return Err(ValidationError::new(
344                1005,
345                "chrgs_id does not match the required pattern".to_string(),
346            ));
347        }
348        for item in &self.rcrd {
349            item.validate()?
350        }
351        Ok(())
352    }
353}
354
355// ChargesPerTransactionRecord31: Further information related to the processing of the payment adjustment instruction that may need to be acted upon by the next agent.
356#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
357pub struct ChargesPerTransactionRecord31 {
358    #[serde(rename = "RcrdId", skip_serializing_if = "Option::is_none")]
359    pub rcrd_id: Option<String>,
360    #[serde(rename = "ChrgsRqstr")]
361    pub chrgs_rqstr: BranchAndFinancialInstitutionIdentification81,
362    #[serde(rename = "UndrlygTx")]
363    pub undrlyg_tx: TransactionReferences71,
364    #[serde(rename = "TtlChrgsPerRcrd")]
365    pub ttl_chrgs_per_rcrd: TotalCharges81,
366    #[serde(rename = "ChrgsBrkdwn")]
367    pub chrgs_brkdwn: Vec<ChargesBreakdown11>,
368    #[serde(rename = "DbtrAgt", skip_serializing_if = "Option::is_none")]
369    pub dbtr_agt: Option<BranchAndFinancialInstitutionIdentification81>,
370    #[serde(rename = "DbtrAgtAcct", skip_serializing_if = "Option::is_none")]
371    pub dbtr_agt_acct: Option<CashAccount401>,
372    #[serde(rename = "InstrForInstdAgt", skip_serializing_if = "Option::is_none")]
373    pub instr_for_instd_agt: Option<InstructionForInstructedAgent11>,
374}
375
376impl ChargesPerTransactionRecord31 {
377    pub fn validate(&self) -> Result<(), ValidationError> {
378        if let Some(ref val) = self.rcrd_id {
379            if val.chars().count() < 1 {
380                return Err(ValidationError::new(
381                    1001,
382                    "rcrd_id is shorter than the minimum length of 1".to_string(),
383                ));
384            }
385            if val.chars().count() > 35 {
386                return Err(ValidationError::new(
387                    1002,
388                    "rcrd_id exceeds the maximum length of 35".to_string(),
389                ));
390            }
391            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
392            if !pattern.is_match(val) {
393                return Err(ValidationError::new(
394                    1005,
395                    "rcrd_id does not match the required pattern".to_string(),
396                ));
397            }
398        }
399        self.chrgs_rqstr.validate()?;
400        self.undrlyg_tx.validate()?;
401        self.ttl_chrgs_per_rcrd.validate()?;
402        for item in &self.chrgs_brkdwn {
403            item.validate()?
404        }
405        if let Some(ref val) = self.dbtr_agt {
406            val.validate()?
407        }
408        if let Some(ref val) = self.dbtr_agt_acct {
409            val.validate()?
410        }
411        if let Some(ref val) = self.instr_for_instd_agt {
412            val.validate()?
413        }
414        Ok(())
415    }
416}
417
418// ClearingSystemIdentification2Choice1: Identification of a clearing system, in a coded form as published in an external list.
419#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
420pub struct ClearingSystemIdentification2Choice1 {
421    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
422    pub cd: Option<String>,
423}
424
425impl ClearingSystemIdentification2Choice1 {
426    pub fn validate(&self) -> Result<(), ValidationError> {
427        if let Some(ref val) = self.cd {
428            if val.chars().count() < 1 {
429                return Err(ValidationError::new(
430                    1001,
431                    "cd is shorter than the minimum length of 1".to_string(),
432                ));
433            }
434            if val.chars().count() > 5 {
435                return Err(ValidationError::new(
436                    1002,
437                    "cd exceeds the maximum length of 5".to_string(),
438                ));
439            }
440        }
441        Ok(())
442    }
443}
444
445// ClearingSystemMemberIdentification21: Identification of a member of a clearing system.
446#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
447pub struct ClearingSystemMemberIdentification21 {
448    #[serde(rename = "ClrSysId")]
449    pub clr_sys_id: ClearingSystemIdentification2Choice1,
450    #[serde(rename = "MmbId")]
451    pub mmb_id: String,
452}
453
454impl ClearingSystemMemberIdentification21 {
455    pub fn validate(&self) -> Result<(), ValidationError> {
456        self.clr_sys_id.validate()?;
457        if self.mmb_id.chars().count() < 1 {
458            return Err(ValidationError::new(
459                1001,
460                "mmb_id is shorter than the minimum length of 1".to_string(),
461            ));
462        }
463        if self.mmb_id.chars().count() > 28 {
464            return Err(ValidationError::new(
465                1002,
466                "mmb_id exceeds the maximum length of 28".to_string(),
467            ));
468        }
469        let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
470        if !pattern.is_match(&self.mmb_id) {
471            return Err(ValidationError::new(
472                1005,
473                "mmb_id does not match the required pattern".to_string(),
474            ));
475        }
476        Ok(())
477    }
478}
479
480// CreditDebitCode__1: Operation is a decrease.
481#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
482pub enum CreditDebitCode1 {
483    #[default]
484    #[serde(rename = "DBIT")]
485    CodeDBIT,
486}
487
488impl CreditDebitCode1 {
489    pub fn validate(&self) -> Result<(), ValidationError> {
490        Ok(())
491    }
492}
493
494// FinancialInstitutionIdentification231: Information that locates and identifies a specific address, as defined by postal services.
495#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
496pub struct FinancialInstitutionIdentification231 {
497    #[serde(rename = "BICFI", skip_serializing_if = "Option::is_none")]
498    pub bicfi: Option<String>,
499    #[serde(rename = "ClrSysMmbId", skip_serializing_if = "Option::is_none")]
500    pub clr_sys_mmb_id: Option<ClearingSystemMemberIdentification21>,
501    #[serde(rename = "LEI", skip_serializing_if = "Option::is_none")]
502    pub lei: Option<String>,
503    #[serde(rename = "Nm", skip_serializing_if = "Option::is_none")]
504    pub nm: Option<String>,
505    #[serde(rename = "PstlAdr", skip_serializing_if = "Option::is_none")]
506    pub pstl_adr: Option<PostalAddress271>,
507}
508
509impl FinancialInstitutionIdentification231 {
510    pub fn validate(&self) -> Result<(), ValidationError> {
511        if let Some(ref val) = self.bicfi {
512            let pattern =
513                Regex::new("[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}").unwrap();
514            if !pattern.is_match(val) {
515                return Err(ValidationError::new(
516                    1005,
517                    "bicfi does not match the required pattern".to_string(),
518                ));
519            }
520        }
521        if let Some(ref val) = self.clr_sys_mmb_id {
522            val.validate()?
523        }
524        if let Some(ref val) = self.lei {
525            let pattern = Regex::new("[A-Z0-9]{18,18}[0-9]{2,2}").unwrap();
526            if !pattern.is_match(val) {
527                return Err(ValidationError::new(
528                    1005,
529                    "lei does not match the required pattern".to_string(),
530                ));
531            }
532        }
533        if let Some(ref val) = self.nm {
534            if val.chars().count() < 1 {
535                return Err(ValidationError::new(
536                    1001,
537                    "nm is shorter than the minimum length of 1".to_string(),
538                ));
539            }
540            if val.chars().count() > 140 {
541                return Err(ValidationError::new(
542                    1002,
543                    "nm exceeds the maximum length of 140".to_string(),
544                ));
545            }
546            let pattern = Regex::new(
547                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
548            )
549            .unwrap();
550            if !pattern.is_match(val) {
551                return Err(ValidationError::new(
552                    1005,
553                    "nm does not match the required pattern".to_string(),
554                ));
555            }
556        }
557        if let Some(ref val) = self.pstl_adr {
558            val.validate()?
559        }
560        Ok(())
561    }
562}
563
564// GenericAccountIdentification11: Entity that assigns the identification.
565#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
566pub struct GenericAccountIdentification11 {
567    #[serde(rename = "Id")]
568    pub id: String,
569    #[serde(rename = "SchmeNm", skip_serializing_if = "Option::is_none")]
570    pub schme_nm: Option<AccountSchemeName1Choice1>,
571    #[serde(rename = "Issr", skip_serializing_if = "Option::is_none")]
572    pub issr: Option<String>,
573}
574
575impl GenericAccountIdentification11 {
576    pub fn validate(&self) -> Result<(), ValidationError> {
577        if self.id.chars().count() < 1 {
578            return Err(ValidationError::new(
579                1001,
580                "id is shorter than the minimum length of 1".to_string(),
581            ));
582        }
583        if self.id.chars().count() > 34 {
584            return Err(ValidationError::new(
585                1002,
586                "id exceeds the maximum length of 34".to_string(),
587            ));
588        }
589        let pattern = Regex::new("([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]*(/[0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ])?)*)").unwrap();
590        if !pattern.is_match(&self.id) {
591            return Err(ValidationError::new(
592                1005,
593                "id does not match the required pattern".to_string(),
594            ));
595        }
596        if let Some(ref val) = self.schme_nm {
597            val.validate()?
598        }
599        if let Some(ref val) = self.issr {
600            if val.chars().count() < 1 {
601                return Err(ValidationError::new(
602                    1001,
603                    "issr is shorter than the minimum length of 1".to_string(),
604                ));
605            }
606            if val.chars().count() > 35 {
607                return Err(ValidationError::new(
608                    1002,
609                    "issr exceeds the maximum length of 35".to_string(),
610                ));
611            }
612            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
613            if !pattern.is_match(val) {
614                return Err(ValidationError::new(
615                    1005,
616                    "issr does not match the required pattern".to_string(),
617                ));
618            }
619        }
620        Ok(())
621    }
622}
623
624// GroupHeader1151: Account of the agent that services the charges account.
625#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
626pub struct GroupHeader1151 {
627    #[serde(rename = "MsgId")]
628    pub msg_id: String,
629    #[serde(rename = "CreDtTm")]
630    pub cre_dt_tm: String,
631    #[serde(rename = "TtlChrgs")]
632    pub ttl_chrgs: TotalCharges71,
633    #[serde(rename = "ChrgsAcctAgt", skip_serializing_if = "Option::is_none")]
634    pub chrgs_acct_agt: Option<BranchAndFinancialInstitutionIdentification81>,
635    #[serde(rename = "ChrgsAcctAgtAcct", skip_serializing_if = "Option::is_none")]
636    pub chrgs_acct_agt_acct: Option<CashAccount401>,
637}
638
639impl GroupHeader1151 {
640    pub fn validate(&self) -> Result<(), ValidationError> {
641        if self.msg_id.chars().count() < 1 {
642            return Err(ValidationError::new(
643                1001,
644                "msg_id is shorter than the minimum length of 1".to_string(),
645            ));
646        }
647        if self.msg_id.chars().count() > 35 {
648            return Err(ValidationError::new(
649                1002,
650                "msg_id exceeds the maximum length of 35".to_string(),
651            ));
652        }
653        let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
654        if !pattern.is_match(&self.msg_id) {
655            return Err(ValidationError::new(
656                1005,
657                "msg_id does not match the required pattern".to_string(),
658            ));
659        }
660        let pattern = Regex::new(".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]").unwrap();
661        if !pattern.is_match(&self.cre_dt_tm) {
662            return Err(ValidationError::new(
663                1005,
664                "cre_dt_tm does not match the required pattern".to_string(),
665            ));
666        }
667        self.ttl_chrgs.validate()?;
668        if let Some(ref val) = self.chrgs_acct_agt {
669            val.validate()?
670        }
671        if let Some(ref val) = self.chrgs_acct_agt_acct {
672            val.validate()?
673        }
674        Ok(())
675    }
676}
677
678// InstructionForInstructedAgent11: Further information complementing the coded instruction or instruction to the instructed agent that is bilaterally agreed or specific to a user community.
679#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
680pub struct InstructionForInstructedAgent11 {
681    #[serde(rename = "Cd")]
682    pub cd: String,
683    #[serde(rename = "InstrInf", skip_serializing_if = "Option::is_none")]
684    pub instr_inf: Option<String>,
685}
686
687impl InstructionForInstructedAgent11 {
688    pub fn validate(&self) -> Result<(), ValidationError> {
689        if self.cd.chars().count() < 1 {
690            return Err(ValidationError::new(
691                1001,
692                "cd is shorter than the minimum length of 1".to_string(),
693            ));
694        }
695        if self.cd.chars().count() > 4 {
696            return Err(ValidationError::new(
697                1002,
698                "cd exceeds the maximum length of 4".to_string(),
699            ));
700        }
701        if let Some(ref val) = self.instr_inf {
702            if val.chars().count() < 1 {
703                return Err(ValidationError::new(
704                    1001,
705                    "instr_inf is shorter than the minimum length of 1".to_string(),
706                ));
707            }
708            if val.chars().count() > 140 {
709                return Err(ValidationError::new(
710                    1002,
711                    "instr_inf exceeds the maximum length of 140".to_string(),
712                ));
713            }
714            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
715            if !pattern.is_match(val) {
716                return Err(ValidationError::new(
717                    1005,
718                    "instr_inf does not match the required pattern".to_string(),
719                ));
720            }
721        }
722        Ok(())
723    }
724}
725
726// PostalAddress271: Information that locates and identifies a specific address, as defined by postal services, presented in free format text.
727#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
728pub struct PostalAddress271 {
729    #[serde(rename = "Dept", skip_serializing_if = "Option::is_none")]
730    pub dept: Option<String>,
731    #[serde(rename = "SubDept", skip_serializing_if = "Option::is_none")]
732    pub sub_dept: Option<String>,
733    #[serde(rename = "StrtNm", skip_serializing_if = "Option::is_none")]
734    pub strt_nm: Option<String>,
735    #[serde(rename = "BldgNb", skip_serializing_if = "Option::is_none")]
736    pub bldg_nb: Option<String>,
737    #[serde(rename = "BldgNm", skip_serializing_if = "Option::is_none")]
738    pub bldg_nm: Option<String>,
739    #[serde(rename = "Flr", skip_serializing_if = "Option::is_none")]
740    pub flr: Option<String>,
741    #[serde(rename = "PstBx", skip_serializing_if = "Option::is_none")]
742    pub pst_bx: Option<String>,
743    #[serde(rename = "Room", skip_serializing_if = "Option::is_none")]
744    pub room: Option<String>,
745    #[serde(rename = "PstCd", skip_serializing_if = "Option::is_none")]
746    pub pst_cd: Option<String>,
747    #[serde(rename = "TwnNm", skip_serializing_if = "Option::is_none")]
748    pub twn_nm: Option<String>,
749    #[serde(rename = "TwnLctnNm", skip_serializing_if = "Option::is_none")]
750    pub twn_lctn_nm: Option<String>,
751    #[serde(rename = "DstrctNm", skip_serializing_if = "Option::is_none")]
752    pub dstrct_nm: Option<String>,
753    #[serde(rename = "CtrySubDvsn", skip_serializing_if = "Option::is_none")]
754    pub ctry_sub_dvsn: Option<String>,
755    #[serde(rename = "Ctry", skip_serializing_if = "Option::is_none")]
756    pub ctry: Option<String>,
757    #[serde(rename = "AdrLine", skip_serializing_if = "Option::is_none")]
758    pub adr_line: Option<Vec<String>>,
759}
760
761impl PostalAddress271 {
762    pub fn validate(&self) -> Result<(), ValidationError> {
763        if let Some(ref val) = self.dept {
764            if val.chars().count() < 1 {
765                return Err(ValidationError::new(
766                    1001,
767                    "dept is shorter than the minimum length of 1".to_string(),
768                ));
769            }
770            if val.chars().count() > 70 {
771                return Err(ValidationError::new(
772                    1002,
773                    "dept exceeds the maximum length of 70".to_string(),
774                ));
775            }
776            let pattern = Regex::new(
777                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
778            )
779            .unwrap();
780            if !pattern.is_match(val) {
781                return Err(ValidationError::new(
782                    1005,
783                    "dept does not match the required pattern".to_string(),
784                ));
785            }
786        }
787        if let Some(ref val) = self.sub_dept {
788            if val.chars().count() < 1 {
789                return Err(ValidationError::new(
790                    1001,
791                    "sub_dept is shorter than the minimum length of 1".to_string(),
792                ));
793            }
794            if val.chars().count() > 70 {
795                return Err(ValidationError::new(
796                    1002,
797                    "sub_dept exceeds the maximum length of 70".to_string(),
798                ));
799            }
800            let pattern = Regex::new(
801                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
802            )
803            .unwrap();
804            if !pattern.is_match(val) {
805                return Err(ValidationError::new(
806                    1005,
807                    "sub_dept does not match the required pattern".to_string(),
808                ));
809            }
810        }
811        if let Some(ref val) = self.strt_nm {
812            if val.chars().count() < 1 {
813                return Err(ValidationError::new(
814                    1001,
815                    "strt_nm is shorter than the minimum length of 1".to_string(),
816                ));
817            }
818            if val.chars().count() > 70 {
819                return Err(ValidationError::new(
820                    1002,
821                    "strt_nm exceeds the maximum length of 70".to_string(),
822                ));
823            }
824            let pattern = Regex::new(
825                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
826            )
827            .unwrap();
828            if !pattern.is_match(val) {
829                return Err(ValidationError::new(
830                    1005,
831                    "strt_nm does not match the required pattern".to_string(),
832                ));
833            }
834        }
835        if let Some(ref val) = self.bldg_nb {
836            if val.chars().count() < 1 {
837                return Err(ValidationError::new(
838                    1001,
839                    "bldg_nb is shorter than the minimum length of 1".to_string(),
840                ));
841            }
842            if val.chars().count() > 16 {
843                return Err(ValidationError::new(
844                    1002,
845                    "bldg_nb exceeds the maximum length of 16".to_string(),
846                ));
847            }
848            let pattern = Regex::new(
849                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
850            )
851            .unwrap();
852            if !pattern.is_match(val) {
853                return Err(ValidationError::new(
854                    1005,
855                    "bldg_nb does not match the required pattern".to_string(),
856                ));
857            }
858        }
859        if let Some(ref val) = self.bldg_nm {
860            if val.chars().count() < 1 {
861                return Err(ValidationError::new(
862                    1001,
863                    "bldg_nm is shorter than the minimum length of 1".to_string(),
864                ));
865            }
866            if val.chars().count() > 35 {
867                return Err(ValidationError::new(
868                    1002,
869                    "bldg_nm exceeds the maximum length of 35".to_string(),
870                ));
871            }
872            let pattern = Regex::new(
873                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
874            )
875            .unwrap();
876            if !pattern.is_match(val) {
877                return Err(ValidationError::new(
878                    1005,
879                    "bldg_nm does not match the required pattern".to_string(),
880                ));
881            }
882        }
883        if let Some(ref val) = self.flr {
884            if val.chars().count() < 1 {
885                return Err(ValidationError::new(
886                    1001,
887                    "flr is shorter than the minimum length of 1".to_string(),
888                ));
889            }
890            if val.chars().count() > 70 {
891                return Err(ValidationError::new(
892                    1002,
893                    "flr exceeds the maximum length of 70".to_string(),
894                ));
895            }
896            let pattern = Regex::new(
897                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
898            )
899            .unwrap();
900            if !pattern.is_match(val) {
901                return Err(ValidationError::new(
902                    1005,
903                    "flr does not match the required pattern".to_string(),
904                ));
905            }
906        }
907        if let Some(ref val) = self.pst_bx {
908            if val.chars().count() < 1 {
909                return Err(ValidationError::new(
910                    1001,
911                    "pst_bx is shorter than the minimum length of 1".to_string(),
912                ));
913            }
914            if val.chars().count() > 16 {
915                return Err(ValidationError::new(
916                    1002,
917                    "pst_bx exceeds the maximum length of 16".to_string(),
918                ));
919            }
920            let pattern = Regex::new(
921                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
922            )
923            .unwrap();
924            if !pattern.is_match(val) {
925                return Err(ValidationError::new(
926                    1005,
927                    "pst_bx does not match the required pattern".to_string(),
928                ));
929            }
930        }
931        if let Some(ref val) = self.room {
932            if val.chars().count() < 1 {
933                return Err(ValidationError::new(
934                    1001,
935                    "room is shorter than the minimum length of 1".to_string(),
936                ));
937            }
938            if val.chars().count() > 70 {
939                return Err(ValidationError::new(
940                    1002,
941                    "room exceeds the maximum length of 70".to_string(),
942                ));
943            }
944            let pattern = Regex::new(
945                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
946            )
947            .unwrap();
948            if !pattern.is_match(val) {
949                return Err(ValidationError::new(
950                    1005,
951                    "room does not match the required pattern".to_string(),
952                ));
953            }
954        }
955        if let Some(ref val) = self.pst_cd {
956            if val.chars().count() < 1 {
957                return Err(ValidationError::new(
958                    1001,
959                    "pst_cd is shorter than the minimum length of 1".to_string(),
960                ));
961            }
962            if val.chars().count() > 16 {
963                return Err(ValidationError::new(
964                    1002,
965                    "pst_cd exceeds the maximum length of 16".to_string(),
966                ));
967            }
968            let pattern = Regex::new(
969                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
970            )
971            .unwrap();
972            if !pattern.is_match(val) {
973                return Err(ValidationError::new(
974                    1005,
975                    "pst_cd does not match the required pattern".to_string(),
976                ));
977            }
978        }
979        if let Some(ref val) = self.twn_nm {
980            if val.chars().count() < 1 {
981                return Err(ValidationError::new(
982                    1001,
983                    "twn_nm is shorter than the minimum length of 1".to_string(),
984                ));
985            }
986            if val.chars().count() > 35 {
987                return Err(ValidationError::new(
988                    1002,
989                    "twn_nm exceeds the maximum length of 35".to_string(),
990                ));
991            }
992            let pattern = Regex::new(
993                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
994            )
995            .unwrap();
996            if !pattern.is_match(val) {
997                return Err(ValidationError::new(
998                    1005,
999                    "twn_nm does not match the required pattern".to_string(),
1000                ));
1001            }
1002        }
1003        if let Some(ref val) = self.twn_lctn_nm {
1004            if val.chars().count() < 1 {
1005                return Err(ValidationError::new(
1006                    1001,
1007                    "twn_lctn_nm is shorter than the minimum length of 1".to_string(),
1008                ));
1009            }
1010            if val.chars().count() > 35 {
1011                return Err(ValidationError::new(
1012                    1002,
1013                    "twn_lctn_nm exceeds the maximum length of 35".to_string(),
1014                ));
1015            }
1016            let pattern = Regex::new(
1017                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1018            )
1019            .unwrap();
1020            if !pattern.is_match(val) {
1021                return Err(ValidationError::new(
1022                    1005,
1023                    "twn_lctn_nm does not match the required pattern".to_string(),
1024                ));
1025            }
1026        }
1027        if let Some(ref val) = self.dstrct_nm {
1028            if val.chars().count() < 1 {
1029                return Err(ValidationError::new(
1030                    1001,
1031                    "dstrct_nm is shorter than the minimum length of 1".to_string(),
1032                ));
1033            }
1034            if val.chars().count() > 35 {
1035                return Err(ValidationError::new(
1036                    1002,
1037                    "dstrct_nm exceeds the maximum length of 35".to_string(),
1038                ));
1039            }
1040            let pattern = Regex::new(
1041                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1042            )
1043            .unwrap();
1044            if !pattern.is_match(val) {
1045                return Err(ValidationError::new(
1046                    1005,
1047                    "dstrct_nm does not match the required pattern".to_string(),
1048                ));
1049            }
1050        }
1051        if let Some(ref val) = self.ctry_sub_dvsn {
1052            if val.chars().count() < 1 {
1053                return Err(ValidationError::new(
1054                    1001,
1055                    "ctry_sub_dvsn is shorter than the minimum length of 1".to_string(),
1056                ));
1057            }
1058            if val.chars().count() > 35 {
1059                return Err(ValidationError::new(
1060                    1002,
1061                    "ctry_sub_dvsn exceeds the maximum length of 35".to_string(),
1062                ));
1063            }
1064            let pattern = Regex::new(
1065                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1066            )
1067            .unwrap();
1068            if !pattern.is_match(val) {
1069                return Err(ValidationError::new(
1070                    1005,
1071                    "ctry_sub_dvsn does not match the required pattern".to_string(),
1072                ));
1073            }
1074        }
1075        if let Some(ref val) = self.ctry {
1076            let pattern = Regex::new("[A-Z]{2,2}").unwrap();
1077            if !pattern.is_match(val) {
1078                return Err(ValidationError::new(
1079                    1005,
1080                    "ctry does not match the required pattern".to_string(),
1081                ));
1082            }
1083        }
1084        if let Some(ref vec) = self.adr_line {
1085            for item in vec {
1086                if item.chars().count() < 1 {
1087                    return Err(ValidationError::new(
1088                        1001,
1089                        "adr_line is shorter than the minimum length of 1".to_string(),
1090                    ));
1091                }
1092                if item.chars().count() > 70 {
1093                    return Err(ValidationError::new(
1094                        1002,
1095                        "adr_line exceeds the maximum length of 70".to_string(),
1096                    ));
1097                }
1098                let pattern = Regex::new(
1099                    "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1100                )
1101                .unwrap();
1102                if !pattern.is_match(&item) {
1103                    return Err(ValidationError::new(
1104                        1005,
1105                        "adr_line does not match the required pattern".to_string(),
1106                    ));
1107                }
1108            }
1109        }
1110        Ok(())
1111    }
1112}
1113
1114// ProxyAccountIdentification11: Identification used to indicate the account identification under another specified name.
1115#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1116pub struct ProxyAccountIdentification11 {
1117    #[serde(rename = "Tp", skip_serializing_if = "Option::is_none")]
1118    pub tp: Option<ProxyAccountType1Choice1>,
1119    #[serde(rename = "Id")]
1120    pub id: String,
1121}
1122
1123impl ProxyAccountIdentification11 {
1124    pub fn validate(&self) -> Result<(), ValidationError> {
1125        if let Some(ref val) = self.tp {
1126            val.validate()?
1127        }
1128        if self.id.chars().count() < 1 {
1129            return Err(ValidationError::new(
1130                1001,
1131                "id is shorter than the minimum length of 1".to_string(),
1132            ));
1133        }
1134        if self.id.chars().count() > 320 {
1135            return Err(ValidationError::new(
1136                1002,
1137                "id exceeds the maximum length of 320".to_string(),
1138            ));
1139        }
1140        let pattern =
1141            Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+")
1142                .unwrap();
1143        if !pattern.is_match(&self.id) {
1144            return Err(ValidationError::new(
1145                1005,
1146                "id does not match the required pattern".to_string(),
1147            ));
1148        }
1149        Ok(())
1150    }
1151}
1152
1153// ProxyAccountType1Choice1: Name of the identification scheme, in a free text form.
1154#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1155pub struct ProxyAccountType1Choice1 {
1156    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1157    pub cd: Option<String>,
1158    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1159    pub prtry: Option<String>,
1160}
1161
1162impl ProxyAccountType1Choice1 {
1163    pub fn validate(&self) -> Result<(), ValidationError> {
1164        if let Some(ref val) = self.cd {
1165            if val.chars().count() < 1 {
1166                return Err(ValidationError::new(
1167                    1001,
1168                    "cd is shorter than the minimum length of 1".to_string(),
1169                ));
1170            }
1171            if val.chars().count() > 4 {
1172                return Err(ValidationError::new(
1173                    1002,
1174                    "cd exceeds the maximum length of 4".to_string(),
1175                ));
1176            }
1177        }
1178        if let Some(ref val) = self.prtry {
1179            if val.chars().count() < 1 {
1180                return Err(ValidationError::new(
1181                    1001,
1182                    "prtry is shorter than the minimum length of 1".to_string(),
1183                ));
1184            }
1185            if val.chars().count() > 35 {
1186                return Err(ValidationError::new(
1187                    1002,
1188                    "prtry exceeds the maximum length of 35".to_string(),
1189                ));
1190            }
1191            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1192            if !pattern.is_match(val) {
1193                return Err(ValidationError::new(
1194                    1005,
1195                    "prtry does not match the required pattern".to_string(),
1196                ));
1197            }
1198        }
1199        Ok(())
1200    }
1201}
1202
1203// TotalCharges71: Indicates whether the total charges amount is a credit or a debit amount.
1204// Usage: A zero amount is considered to be a credit.
1205#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1206pub struct TotalCharges71 {
1207    #[serde(rename = "NbOfChrgsRcrds")]
1208    pub nb_of_chrgs_rcrds: String,
1209    #[serde(rename = "TtlChrgsAmt")]
1210    pub ttl_chrgs_amt: CBPRAmount,
1211    #[serde(rename = "CdtDbtInd")]
1212    pub cdt_dbt_ind: CreditDebitCode1,
1213}
1214
1215impl TotalCharges71 {
1216    pub fn validate(&self) -> Result<(), ValidationError> {
1217        let pattern = Regex::new("[0-9]{1,15}").unwrap();
1218        if !pattern.is_match(&self.nb_of_chrgs_rcrds) {
1219            return Err(ValidationError::new(
1220                1005,
1221                "nb_of_chrgs_rcrds does not match the required pattern".to_string(),
1222            ));
1223        }
1224        self.ttl_chrgs_amt.validate()?;
1225        self.cdt_dbt_ind.validate()?;
1226        Ok(())
1227    }
1228}
1229
1230// TotalCharges81: Indicates whether the total charges amount is a credit or a debit amount.
1231// Usage: A zero amount is considered to be a credit.
1232#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1233pub struct TotalCharges81 {
1234    #[serde(rename = "NbOfChrgsBrkdwnItms")]
1235    pub nb_of_chrgs_brkdwn_itms: String,
1236    #[serde(rename = "TtlChrgsAmt")]
1237    pub ttl_chrgs_amt: CBPRAmount,
1238    #[serde(rename = "CdtDbtInd")]
1239    pub cdt_dbt_ind: CreditDebitCode1,
1240}
1241
1242impl TotalCharges81 {
1243    pub fn validate(&self) -> Result<(), ValidationError> {
1244        let pattern = Regex::new("[0-9]{1,15}").unwrap();
1245        if !pattern.is_match(&self.nb_of_chrgs_brkdwn_itms) {
1246            return Err(ValidationError::new(
1247                1005,
1248                "nb_of_chrgs_brkdwn_itms does not match the required pattern".to_string(),
1249            ));
1250        }
1251        self.ttl_chrgs_amt.validate()?;
1252        self.cdt_dbt_ind.validate()?;
1253        Ok(())
1254    }
1255}
1256
1257// TransactionReferences71: Identification of the securities transaction assigned by the processor of the instruction other than the securities account owner, the securities account servicer and the market infrastructure.
1258#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1259pub struct TransactionReferences71 {
1260    #[serde(rename = "MsgId", skip_serializing_if = "Option::is_none")]
1261    pub msg_id: Option<String>,
1262    #[serde(rename = "MsgNmId")]
1263    pub msg_nm_id: String,
1264    #[serde(rename = "AcctSvcrRef", skip_serializing_if = "Option::is_none")]
1265    pub acct_svcr_ref: Option<String>,
1266    #[serde(rename = "PmtInfId", skip_serializing_if = "Option::is_none")]
1267    pub pmt_inf_id: Option<String>,
1268    #[serde(rename = "InstrId", skip_serializing_if = "Option::is_none")]
1269    pub instr_id: Option<String>,
1270    #[serde(rename = "EndToEndId", skip_serializing_if = "Option::is_none")]
1271    pub end_to_end_id: Option<String>,
1272    #[serde(rename = "UETR", skip_serializing_if = "Option::is_none")]
1273    pub uetr: Option<String>,
1274    #[serde(rename = "TxId", skip_serializing_if = "Option::is_none")]
1275    pub tx_id: Option<String>,
1276    #[serde(rename = "MndtId", skip_serializing_if = "Option::is_none")]
1277    pub mndt_id: Option<String>,
1278    #[serde(rename = "ChqNb", skip_serializing_if = "Option::is_none")]
1279    pub chq_nb: Option<String>,
1280    #[serde(rename = "AcctOwnrTxId", skip_serializing_if = "Option::is_none")]
1281    pub acct_ownr_tx_id: Option<String>,
1282    #[serde(rename = "AcctSvcrTxId", skip_serializing_if = "Option::is_none")]
1283    pub acct_svcr_tx_id: Option<String>,
1284    #[serde(rename = "PrcgId", skip_serializing_if = "Option::is_none")]
1285    pub prcg_id: Option<String>,
1286}
1287
1288impl TransactionReferences71 {
1289    pub fn validate(&self) -> Result<(), ValidationError> {
1290        if let Some(ref val) = self.msg_id {
1291            if val.chars().count() < 1 {
1292                return Err(ValidationError::new(
1293                    1001,
1294                    "msg_id is shorter than the minimum length of 1".to_string(),
1295                ));
1296            }
1297            if val.chars().count() > 35 {
1298                return Err(ValidationError::new(
1299                    1002,
1300                    "msg_id exceeds the maximum length of 35".to_string(),
1301                ));
1302            }
1303            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1304            if !pattern.is_match(val) {
1305                return Err(ValidationError::new(
1306                    1005,
1307                    "msg_id does not match the required pattern".to_string(),
1308                ));
1309            }
1310        }
1311        if self.msg_nm_id.chars().count() < 1 {
1312            return Err(ValidationError::new(
1313                1001,
1314                "msg_nm_id is shorter than the minimum length of 1".to_string(),
1315            ));
1316        }
1317        if self.msg_nm_id.chars().count() > 35 {
1318            return Err(ValidationError::new(
1319                1002,
1320                "msg_nm_id exceeds the maximum length of 35".to_string(),
1321            ));
1322        }
1323        let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1324        if !pattern.is_match(&self.msg_nm_id) {
1325            return Err(ValidationError::new(
1326                1005,
1327                "msg_nm_id does not match the required pattern".to_string(),
1328            ));
1329        }
1330        if let Some(ref val) = self.acct_svcr_ref {
1331            if val.chars().count() < 1 {
1332                return Err(ValidationError::new(
1333                    1001,
1334                    "acct_svcr_ref is shorter than the minimum length of 1".to_string(),
1335                ));
1336            }
1337            if val.chars().count() > 35 {
1338                return Err(ValidationError::new(
1339                    1002,
1340                    "acct_svcr_ref exceeds the maximum length of 35".to_string(),
1341                ));
1342            }
1343            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1344            if !pattern.is_match(val) {
1345                return Err(ValidationError::new(
1346                    1005,
1347                    "acct_svcr_ref does not match the required pattern".to_string(),
1348                ));
1349            }
1350        }
1351        if let Some(ref val) = self.pmt_inf_id {
1352            if val.chars().count() < 1 {
1353                return Err(ValidationError::new(
1354                    1001,
1355                    "pmt_inf_id is shorter than the minimum length of 1".to_string(),
1356                ));
1357            }
1358            if val.chars().count() > 35 {
1359                return Err(ValidationError::new(
1360                    1002,
1361                    "pmt_inf_id exceeds the maximum length of 35".to_string(),
1362                ));
1363            }
1364            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1365            if !pattern.is_match(val) {
1366                return Err(ValidationError::new(
1367                    1005,
1368                    "pmt_inf_id does not match the required pattern".to_string(),
1369                ));
1370            }
1371        }
1372        if let Some(ref val) = self.instr_id {
1373            if val.chars().count() < 1 {
1374                return Err(ValidationError::new(
1375                    1001,
1376                    "instr_id is shorter than the minimum length of 1".to_string(),
1377                ));
1378            }
1379            if val.chars().count() > 16 {
1380                return Err(ValidationError::new(
1381                    1002,
1382                    "instr_id exceeds the maximum length of 16".to_string(),
1383                ));
1384            }
1385            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1386            if !pattern.is_match(val) {
1387                return Err(ValidationError::new(
1388                    1005,
1389                    "instr_id does not match the required pattern".to_string(),
1390                ));
1391            }
1392        }
1393        if let Some(ref val) = self.end_to_end_id {
1394            if val.chars().count() < 1 {
1395                return Err(ValidationError::new(
1396                    1001,
1397                    "end_to_end_id is shorter than the minimum length of 1".to_string(),
1398                ));
1399            }
1400            if val.chars().count() > 35 {
1401                return Err(ValidationError::new(
1402                    1002,
1403                    "end_to_end_id exceeds the maximum length of 35".to_string(),
1404                ));
1405            }
1406            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1407            if !pattern.is_match(val) {
1408                return Err(ValidationError::new(
1409                    1005,
1410                    "end_to_end_id does not match the required pattern".to_string(),
1411                ));
1412            }
1413        }
1414        if let Some(ref val) = self.uetr {
1415            let pattern =
1416                Regex::new("[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}")
1417                    .unwrap();
1418            if !pattern.is_match(val) {
1419                return Err(ValidationError::new(
1420                    1005,
1421                    "uetr does not match the required pattern".to_string(),
1422                ));
1423            }
1424        }
1425        if let Some(ref val) = self.tx_id {
1426            if val.chars().count() < 1 {
1427                return Err(ValidationError::new(
1428                    1001,
1429                    "tx_id is shorter than the minimum length of 1".to_string(),
1430                ));
1431            }
1432            if val.chars().count() > 35 {
1433                return Err(ValidationError::new(
1434                    1002,
1435                    "tx_id exceeds the maximum length of 35".to_string(),
1436                ));
1437            }
1438            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1439            if !pattern.is_match(val) {
1440                return Err(ValidationError::new(
1441                    1005,
1442                    "tx_id does not match the required pattern".to_string(),
1443                ));
1444            }
1445        }
1446        if let Some(ref val) = self.mndt_id {
1447            if val.chars().count() < 1 {
1448                return Err(ValidationError::new(
1449                    1001,
1450                    "mndt_id is shorter than the minimum length of 1".to_string(),
1451                ));
1452            }
1453            if val.chars().count() > 35 {
1454                return Err(ValidationError::new(
1455                    1002,
1456                    "mndt_id exceeds the maximum length of 35".to_string(),
1457                ));
1458            }
1459            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1460            if !pattern.is_match(val) {
1461                return Err(ValidationError::new(
1462                    1005,
1463                    "mndt_id does not match the required pattern".to_string(),
1464                ));
1465            }
1466        }
1467        if let Some(ref val) = self.chq_nb {
1468            if val.chars().count() < 1 {
1469                return Err(ValidationError::new(
1470                    1001,
1471                    "chq_nb is shorter than the minimum length of 1".to_string(),
1472                ));
1473            }
1474            if val.chars().count() > 35 {
1475                return Err(ValidationError::new(
1476                    1002,
1477                    "chq_nb exceeds the maximum length of 35".to_string(),
1478                ));
1479            }
1480            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1481            if !pattern.is_match(val) {
1482                return Err(ValidationError::new(
1483                    1005,
1484                    "chq_nb does not match the required pattern".to_string(),
1485                ));
1486            }
1487        }
1488        if let Some(ref val) = self.acct_ownr_tx_id {
1489            if val.chars().count() < 1 {
1490                return Err(ValidationError::new(
1491                    1001,
1492                    "acct_ownr_tx_id is shorter than the minimum length of 1".to_string(),
1493                ));
1494            }
1495            if val.chars().count() > 35 {
1496                return Err(ValidationError::new(
1497                    1002,
1498                    "acct_ownr_tx_id exceeds the maximum length of 35".to_string(),
1499                ));
1500            }
1501            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1502            if !pattern.is_match(val) {
1503                return Err(ValidationError::new(
1504                    1005,
1505                    "acct_ownr_tx_id does not match the required pattern".to_string(),
1506                ));
1507            }
1508        }
1509        if let Some(ref val) = self.acct_svcr_tx_id {
1510            if val.chars().count() < 1 {
1511                return Err(ValidationError::new(
1512                    1001,
1513                    "acct_svcr_tx_id is shorter than the minimum length of 1".to_string(),
1514                ));
1515            }
1516            if val.chars().count() > 35 {
1517                return Err(ValidationError::new(
1518                    1002,
1519                    "acct_svcr_tx_id exceeds the maximum length of 35".to_string(),
1520                ));
1521            }
1522            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1523            if !pattern.is_match(val) {
1524                return Err(ValidationError::new(
1525                    1005,
1526                    "acct_svcr_tx_id does not match the required pattern".to_string(),
1527                ));
1528            }
1529        }
1530        if let Some(ref val) = self.prcg_id {
1531            if val.chars().count() < 1 {
1532                return Err(ValidationError::new(
1533                    1001,
1534                    "prcg_id is shorter than the minimum length of 1".to_string(),
1535                ));
1536            }
1537            if val.chars().count() > 35 {
1538                return Err(ValidationError::new(
1539                    1002,
1540                    "prcg_id exceeds the maximum length of 35".to_string(),
1541                ));
1542            }
1543            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1544            if !pattern.is_match(val) {
1545                return Err(ValidationError::new(
1546                    1005,
1547                    "prcg_id does not match the required pattern".to_string(),
1548                ));
1549            }
1550        }
1551        Ok(())
1552    }
1553}