mx_message/document/
camt_105_001_02.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// Charges4Choice1: Charges broken down per payment transaction.
266#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
267pub struct Charges4Choice1 {
268    #[serde(rename = "PerTx", skip_serializing_if = "Option::is_none")]
269    pub per_tx: Option<ChargesPerTransaction41>,
270}
271
272impl Charges4Choice1 {
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// ChargesPaymentNotificationV02: 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 ChargesPaymentNotificationV02 {
304    #[serde(rename = "GrpHdr")]
305    pub grp_hdr: GroupHeader1261,
306    #[serde(rename = "Chrgs")]
307    pub chrgs: Charges4Choice1,
308}
309
310impl ChargesPaymentNotificationV02 {
311    pub fn validate(&self) -> Result<(), ValidationError> {
312        self.grp_hdr.validate()?;
313        self.chrgs.validate()?;
314        Ok(())
315    }
316}
317
318// ChargesPerTransaction41: Itemised charges record per transaction.
319#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
320pub struct ChargesPerTransaction41 {
321    #[serde(rename = "ChrgsId")]
322    pub chrgs_id: String,
323    #[serde(rename = "Rcrd")]
324    pub rcrd: ChargesPerTransactionRecord41,
325}
326
327impl ChargesPerTransaction41 {
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        self.rcrd.validate()?;
349        Ok(())
350    }
351}
352
353// ChargesPerTransactionRecord41: Specifies the account of the debtor agent of the initial transaction, when instructing agent is different from the charges account owner.
354#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
355pub struct ChargesPerTransactionRecord41 {
356    #[serde(rename = "UndrlygTx")]
357    pub undrlyg_tx: TransactionReferences71,
358    #[serde(rename = "TtlChrgsPerRcrd")]
359    pub ttl_chrgs_per_rcrd: TotalCharges81,
360    #[serde(rename = "ChrgsBrkdwn")]
361    pub chrgs_brkdwn: Vec<ChargesBreakdown11>,
362    #[serde(rename = "ValDt")]
363    pub val_dt: DateAndDateTime2Choice1,
364    #[serde(rename = "DbtrAgt", skip_serializing_if = "Option::is_none")]
365    pub dbtr_agt: Option<BranchAndFinancialInstitutionIdentification81>,
366    #[serde(rename = "DbtrAgtAcct", skip_serializing_if = "Option::is_none")]
367    pub dbtr_agt_acct: Option<CashAccount401>,
368}
369
370impl ChargesPerTransactionRecord41 {
371    pub fn validate(&self) -> Result<(), ValidationError> {
372        self.undrlyg_tx.validate()?;
373        self.ttl_chrgs_per_rcrd.validate()?;
374        for item in &self.chrgs_brkdwn {
375            item.validate()?
376        }
377        self.val_dt.validate()?;
378        if let Some(ref val) = self.dbtr_agt {
379            val.validate()?
380        }
381        if let Some(ref val) = self.dbtr_agt_acct {
382            val.validate()?
383        }
384        Ok(())
385    }
386}
387
388// ClearingSystemIdentification2Choice1: Identification of a clearing system, in a coded form as published in an external list.
389#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
390pub struct ClearingSystemIdentification2Choice1 {
391    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
392    pub cd: Option<String>,
393}
394
395impl ClearingSystemIdentification2Choice1 {
396    pub fn validate(&self) -> Result<(), ValidationError> {
397        if let Some(ref val) = self.cd {
398            if val.chars().count() < 1 {
399                return Err(ValidationError::new(
400                    1001,
401                    "cd is shorter than the minimum length of 1".to_string(),
402                ));
403            }
404            if val.chars().count() > 5 {
405                return Err(ValidationError::new(
406                    1002,
407                    "cd exceeds the maximum length of 5".to_string(),
408                ));
409            }
410        }
411        Ok(())
412    }
413}
414
415// ClearingSystemMemberIdentification21: Identification of a member of a clearing system.
416#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
417pub struct ClearingSystemMemberIdentification21 {
418    #[serde(rename = "ClrSysId")]
419    pub clr_sys_id: ClearingSystemIdentification2Choice1,
420    #[serde(rename = "MmbId")]
421    pub mmb_id: String,
422}
423
424impl ClearingSystemMemberIdentification21 {
425    pub fn validate(&self) -> Result<(), ValidationError> {
426        self.clr_sys_id.validate()?;
427        if self.mmb_id.chars().count() < 1 {
428            return Err(ValidationError::new(
429                1001,
430                "mmb_id is shorter than the minimum length of 1".to_string(),
431            ));
432        }
433        if self.mmb_id.chars().count() > 28 {
434            return Err(ValidationError::new(
435                1002,
436                "mmb_id exceeds the maximum length of 28".to_string(),
437            ));
438        }
439        let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
440        if !pattern.is_match(&self.mmb_id) {
441            return Err(ValidationError::new(
442                1005,
443                "mmb_id does not match the required pattern".to_string(),
444            ));
445        }
446        Ok(())
447    }
448}
449
450// CreditDebitCode__1: Operation is a decrease.
451#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
452pub enum CreditDebitCode1 {
453    #[default]
454    #[serde(rename = "DBIT")]
455    CodeDBIT,
456}
457
458impl CreditDebitCode1 {
459    pub fn validate(&self) -> Result<(), ValidationError> {
460        Ok(())
461    }
462}
463
464// DateAndDateTime2Choice1: Specified date.
465#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
466pub struct DateAndDateTime2Choice1 {
467    #[serde(rename = "Dt", skip_serializing_if = "Option::is_none")]
468    pub dt: Option<String>,
469}
470
471impl DateAndDateTime2Choice1 {
472    pub fn validate(&self) -> Result<(), ValidationError> {
473        Ok(())
474    }
475}
476
477// FinancialInstitutionIdentification231: Information that locates and identifies a specific address, as defined by postal services.
478#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
479pub struct FinancialInstitutionIdentification231 {
480    #[serde(rename = "BICFI", skip_serializing_if = "Option::is_none")]
481    pub bicfi: Option<String>,
482    #[serde(rename = "ClrSysMmbId", skip_serializing_if = "Option::is_none")]
483    pub clr_sys_mmb_id: Option<ClearingSystemMemberIdentification21>,
484    #[serde(rename = "LEI", skip_serializing_if = "Option::is_none")]
485    pub lei: Option<String>,
486    #[serde(rename = "Nm", skip_serializing_if = "Option::is_none")]
487    pub nm: Option<String>,
488    #[serde(rename = "PstlAdr", skip_serializing_if = "Option::is_none")]
489    pub pstl_adr: Option<PostalAddress271>,
490}
491
492impl FinancialInstitutionIdentification231 {
493    pub fn validate(&self) -> Result<(), ValidationError> {
494        if let Some(ref val) = self.bicfi {
495            let pattern =
496                Regex::new("[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}").unwrap();
497            if !pattern.is_match(val) {
498                return Err(ValidationError::new(
499                    1005,
500                    "bicfi does not match the required pattern".to_string(),
501                ));
502            }
503        }
504        if let Some(ref val) = self.clr_sys_mmb_id {
505            val.validate()?
506        }
507        if let Some(ref val) = self.lei {
508            let pattern = Regex::new("[A-Z0-9]{18,18}[0-9]{2,2}").unwrap();
509            if !pattern.is_match(val) {
510                return Err(ValidationError::new(
511                    1005,
512                    "lei does not match the required pattern".to_string(),
513                ));
514            }
515        }
516        if let Some(ref val) = self.nm {
517            if val.chars().count() < 1 {
518                return Err(ValidationError::new(
519                    1001,
520                    "nm is shorter than the minimum length of 1".to_string(),
521                ));
522            }
523            if val.chars().count() > 140 {
524                return Err(ValidationError::new(
525                    1002,
526                    "nm exceeds the maximum length of 140".to_string(),
527                ));
528            }
529            let pattern = Regex::new(
530                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
531            )
532            .unwrap();
533            if !pattern.is_match(val) {
534                return Err(ValidationError::new(
535                    1005,
536                    "nm does not match the required pattern".to_string(),
537                ));
538            }
539        }
540        if let Some(ref val) = self.pstl_adr {
541            val.validate()?
542        }
543        Ok(())
544    }
545}
546
547// GenericAccountIdentification11: Entity that assigns the identification.
548#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
549pub struct GenericAccountIdentification11 {
550    #[serde(rename = "Id")]
551    pub id: String,
552    #[serde(rename = "SchmeNm", skip_serializing_if = "Option::is_none")]
553    pub schme_nm: Option<AccountSchemeName1Choice1>,
554    #[serde(rename = "Issr", skip_serializing_if = "Option::is_none")]
555    pub issr: Option<String>,
556}
557
558impl GenericAccountIdentification11 {
559    pub fn validate(&self) -> Result<(), ValidationError> {
560        if self.id.chars().count() < 1 {
561            return Err(ValidationError::new(
562                1001,
563                "id is shorter than the minimum length of 1".to_string(),
564            ));
565        }
566        if self.id.chars().count() > 34 {
567            return Err(ValidationError::new(
568                1002,
569                "id exceeds the maximum length of 34".to_string(),
570            ));
571        }
572        let pattern = Regex::new("([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]*(/[0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ])?)*)").unwrap();
573        if !pattern.is_match(&self.id) {
574            return Err(ValidationError::new(
575                1005,
576                "id does not match the required pattern".to_string(),
577            ));
578        }
579        if let Some(ref val) = self.schme_nm {
580            val.validate()?
581        }
582        if let Some(ref val) = self.issr {
583            if val.chars().count() < 1 {
584                return Err(ValidationError::new(
585                    1001,
586                    "issr is shorter than the minimum length of 1".to_string(),
587                ));
588            }
589            if val.chars().count() > 35 {
590                return Err(ValidationError::new(
591                    1002,
592                    "issr exceeds the maximum length of 35".to_string(),
593                ));
594            }
595            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
596            if !pattern.is_match(val) {
597                return Err(ValidationError::new(
598                    1005,
599                    "issr does not match the required pattern".to_string(),
600                ));
601            }
602        }
603        Ok(())
604    }
605}
606
607// GroupHeader1261: Agent that owns the charges account.
608#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
609pub struct GroupHeader1261 {
610    #[serde(rename = "MsgId")]
611    pub msg_id: String,
612    #[serde(rename = "CreDtTm")]
613    pub cre_dt_tm: String,
614    #[serde(rename = "ChrgsRqstr")]
615    pub chrgs_rqstr: BranchAndFinancialInstitutionIdentification81,
616    #[serde(rename = "ChrgsAcct")]
617    pub chrgs_acct: CashAccount401,
618    #[serde(rename = "ChrgsAcctOwnr", skip_serializing_if = "Option::is_none")]
619    pub chrgs_acct_ownr: Option<BranchAndFinancialInstitutionIdentification81>,
620}
621
622impl GroupHeader1261 {
623    pub fn validate(&self) -> Result<(), ValidationError> {
624        if self.msg_id.chars().count() < 1 {
625            return Err(ValidationError::new(
626                1001,
627                "msg_id is shorter than the minimum length of 1".to_string(),
628            ));
629        }
630        if self.msg_id.chars().count() > 35 {
631            return Err(ValidationError::new(
632                1002,
633                "msg_id exceeds the maximum length of 35".to_string(),
634            ));
635        }
636        let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
637        if !pattern.is_match(&self.msg_id) {
638            return Err(ValidationError::new(
639                1005,
640                "msg_id does not match the required pattern".to_string(),
641            ));
642        }
643        let pattern = Regex::new(".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]").unwrap();
644        if !pattern.is_match(&self.cre_dt_tm) {
645            return Err(ValidationError::new(
646                1005,
647                "cre_dt_tm does not match the required pattern".to_string(),
648            ));
649        }
650        self.chrgs_rqstr.validate()?;
651        self.chrgs_acct.validate()?;
652        if let Some(ref val) = self.chrgs_acct_ownr {
653            val.validate()?
654        }
655        Ok(())
656    }
657}
658
659// PostalAddress271: Information that locates and identifies a specific address, as defined by postal services, presented in free format text.
660#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
661pub struct PostalAddress271 {
662    #[serde(rename = "Dept", skip_serializing_if = "Option::is_none")]
663    pub dept: Option<String>,
664    #[serde(rename = "SubDept", skip_serializing_if = "Option::is_none")]
665    pub sub_dept: Option<String>,
666    #[serde(rename = "StrtNm", skip_serializing_if = "Option::is_none")]
667    pub strt_nm: Option<String>,
668    #[serde(rename = "BldgNb", skip_serializing_if = "Option::is_none")]
669    pub bldg_nb: Option<String>,
670    #[serde(rename = "BldgNm", skip_serializing_if = "Option::is_none")]
671    pub bldg_nm: Option<String>,
672    #[serde(rename = "Flr", skip_serializing_if = "Option::is_none")]
673    pub flr: Option<String>,
674    #[serde(rename = "PstBx", skip_serializing_if = "Option::is_none")]
675    pub pst_bx: Option<String>,
676    #[serde(rename = "Room", skip_serializing_if = "Option::is_none")]
677    pub room: Option<String>,
678    #[serde(rename = "PstCd", skip_serializing_if = "Option::is_none")]
679    pub pst_cd: Option<String>,
680    #[serde(rename = "TwnNm", skip_serializing_if = "Option::is_none")]
681    pub twn_nm: Option<String>,
682    #[serde(rename = "TwnLctnNm", skip_serializing_if = "Option::is_none")]
683    pub twn_lctn_nm: Option<String>,
684    #[serde(rename = "DstrctNm", skip_serializing_if = "Option::is_none")]
685    pub dstrct_nm: Option<String>,
686    #[serde(rename = "CtrySubDvsn", skip_serializing_if = "Option::is_none")]
687    pub ctry_sub_dvsn: Option<String>,
688    #[serde(rename = "Ctry", skip_serializing_if = "Option::is_none")]
689    pub ctry: Option<String>,
690    #[serde(rename = "AdrLine", skip_serializing_if = "Option::is_none")]
691    pub adr_line: Option<Vec<String>>,
692}
693
694impl PostalAddress271 {
695    pub fn validate(&self) -> Result<(), ValidationError> {
696        if let Some(ref val) = self.dept {
697            if val.chars().count() < 1 {
698                return Err(ValidationError::new(
699                    1001,
700                    "dept is shorter than the minimum length of 1".to_string(),
701                ));
702            }
703            if val.chars().count() > 70 {
704                return Err(ValidationError::new(
705                    1002,
706                    "dept exceeds the maximum length of 70".to_string(),
707                ));
708            }
709            let pattern = Regex::new(
710                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
711            )
712            .unwrap();
713            if !pattern.is_match(val) {
714                return Err(ValidationError::new(
715                    1005,
716                    "dept does not match the required pattern".to_string(),
717                ));
718            }
719        }
720        if let Some(ref val) = self.sub_dept {
721            if val.chars().count() < 1 {
722                return Err(ValidationError::new(
723                    1001,
724                    "sub_dept is shorter than the minimum length of 1".to_string(),
725                ));
726            }
727            if val.chars().count() > 70 {
728                return Err(ValidationError::new(
729                    1002,
730                    "sub_dept exceeds the maximum length of 70".to_string(),
731                ));
732            }
733            let pattern = Regex::new(
734                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
735            )
736            .unwrap();
737            if !pattern.is_match(val) {
738                return Err(ValidationError::new(
739                    1005,
740                    "sub_dept does not match the required pattern".to_string(),
741                ));
742            }
743        }
744        if let Some(ref val) = self.strt_nm {
745            if val.chars().count() < 1 {
746                return Err(ValidationError::new(
747                    1001,
748                    "strt_nm is shorter than the minimum length of 1".to_string(),
749                ));
750            }
751            if val.chars().count() > 70 {
752                return Err(ValidationError::new(
753                    1002,
754                    "strt_nm exceeds the maximum length of 70".to_string(),
755                ));
756            }
757            let pattern = Regex::new(
758                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
759            )
760            .unwrap();
761            if !pattern.is_match(val) {
762                return Err(ValidationError::new(
763                    1005,
764                    "strt_nm does not match the required pattern".to_string(),
765                ));
766            }
767        }
768        if let Some(ref val) = self.bldg_nb {
769            if val.chars().count() < 1 {
770                return Err(ValidationError::new(
771                    1001,
772                    "bldg_nb is shorter than the minimum length of 1".to_string(),
773                ));
774            }
775            if val.chars().count() > 16 {
776                return Err(ValidationError::new(
777                    1002,
778                    "bldg_nb exceeds the maximum length of 16".to_string(),
779                ));
780            }
781            let pattern = Regex::new(
782                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
783            )
784            .unwrap();
785            if !pattern.is_match(val) {
786                return Err(ValidationError::new(
787                    1005,
788                    "bldg_nb does not match the required pattern".to_string(),
789                ));
790            }
791        }
792        if let Some(ref val) = self.bldg_nm {
793            if val.chars().count() < 1 {
794                return Err(ValidationError::new(
795                    1001,
796                    "bldg_nm is shorter than the minimum length of 1".to_string(),
797                ));
798            }
799            if val.chars().count() > 35 {
800                return Err(ValidationError::new(
801                    1002,
802                    "bldg_nm exceeds the maximum length of 35".to_string(),
803                ));
804            }
805            let pattern = Regex::new(
806                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
807            )
808            .unwrap();
809            if !pattern.is_match(val) {
810                return Err(ValidationError::new(
811                    1005,
812                    "bldg_nm does not match the required pattern".to_string(),
813                ));
814            }
815        }
816        if let Some(ref val) = self.flr {
817            if val.chars().count() < 1 {
818                return Err(ValidationError::new(
819                    1001,
820                    "flr is shorter than the minimum length of 1".to_string(),
821                ));
822            }
823            if val.chars().count() > 70 {
824                return Err(ValidationError::new(
825                    1002,
826                    "flr exceeds the maximum length of 70".to_string(),
827                ));
828            }
829            let pattern = Regex::new(
830                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
831            )
832            .unwrap();
833            if !pattern.is_match(val) {
834                return Err(ValidationError::new(
835                    1005,
836                    "flr does not match the required pattern".to_string(),
837                ));
838            }
839        }
840        if let Some(ref val) = self.pst_bx {
841            if val.chars().count() < 1 {
842                return Err(ValidationError::new(
843                    1001,
844                    "pst_bx is shorter than the minimum length of 1".to_string(),
845                ));
846            }
847            if val.chars().count() > 16 {
848                return Err(ValidationError::new(
849                    1002,
850                    "pst_bx exceeds the maximum length of 16".to_string(),
851                ));
852            }
853            let pattern = Regex::new(
854                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
855            )
856            .unwrap();
857            if !pattern.is_match(val) {
858                return Err(ValidationError::new(
859                    1005,
860                    "pst_bx does not match the required pattern".to_string(),
861                ));
862            }
863        }
864        if let Some(ref val) = self.room {
865            if val.chars().count() < 1 {
866                return Err(ValidationError::new(
867                    1001,
868                    "room is shorter than the minimum length of 1".to_string(),
869                ));
870            }
871            if val.chars().count() > 70 {
872                return Err(ValidationError::new(
873                    1002,
874                    "room exceeds the maximum length of 70".to_string(),
875                ));
876            }
877            let pattern = Regex::new(
878                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
879            )
880            .unwrap();
881            if !pattern.is_match(val) {
882                return Err(ValidationError::new(
883                    1005,
884                    "room does not match the required pattern".to_string(),
885                ));
886            }
887        }
888        if let Some(ref val) = self.pst_cd {
889            if val.chars().count() < 1 {
890                return Err(ValidationError::new(
891                    1001,
892                    "pst_cd is shorter than the minimum length of 1".to_string(),
893                ));
894            }
895            if val.chars().count() > 16 {
896                return Err(ValidationError::new(
897                    1002,
898                    "pst_cd exceeds the maximum length of 16".to_string(),
899                ));
900            }
901            let pattern = Regex::new(
902                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
903            )
904            .unwrap();
905            if !pattern.is_match(val) {
906                return Err(ValidationError::new(
907                    1005,
908                    "pst_cd does not match the required pattern".to_string(),
909                ));
910            }
911        }
912        if let Some(ref val) = self.twn_nm {
913            if val.chars().count() < 1 {
914                return Err(ValidationError::new(
915                    1001,
916                    "twn_nm is shorter than the minimum length of 1".to_string(),
917                ));
918            }
919            if val.chars().count() > 35 {
920                return Err(ValidationError::new(
921                    1002,
922                    "twn_nm exceeds the maximum length of 35".to_string(),
923                ));
924            }
925            let pattern = Regex::new(
926                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
927            )
928            .unwrap();
929            if !pattern.is_match(val) {
930                return Err(ValidationError::new(
931                    1005,
932                    "twn_nm does not match the required pattern".to_string(),
933                ));
934            }
935        }
936        if let Some(ref val) = self.twn_lctn_nm {
937            if val.chars().count() < 1 {
938                return Err(ValidationError::new(
939                    1001,
940                    "twn_lctn_nm is shorter than the minimum length of 1".to_string(),
941                ));
942            }
943            if val.chars().count() > 35 {
944                return Err(ValidationError::new(
945                    1002,
946                    "twn_lctn_nm exceeds the maximum length of 35".to_string(),
947                ));
948            }
949            let pattern = Regex::new(
950                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
951            )
952            .unwrap();
953            if !pattern.is_match(val) {
954                return Err(ValidationError::new(
955                    1005,
956                    "twn_lctn_nm does not match the required pattern".to_string(),
957                ));
958            }
959        }
960        if let Some(ref val) = self.dstrct_nm {
961            if val.chars().count() < 1 {
962                return Err(ValidationError::new(
963                    1001,
964                    "dstrct_nm is shorter than the minimum length of 1".to_string(),
965                ));
966            }
967            if val.chars().count() > 35 {
968                return Err(ValidationError::new(
969                    1002,
970                    "dstrct_nm exceeds the maximum length of 35".to_string(),
971                ));
972            }
973            let pattern = Regex::new(
974                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
975            )
976            .unwrap();
977            if !pattern.is_match(val) {
978                return Err(ValidationError::new(
979                    1005,
980                    "dstrct_nm does not match the required pattern".to_string(),
981                ));
982            }
983        }
984        if let Some(ref val) = self.ctry_sub_dvsn {
985            if val.chars().count() < 1 {
986                return Err(ValidationError::new(
987                    1001,
988                    "ctry_sub_dvsn is shorter than the minimum length of 1".to_string(),
989                ));
990            }
991            if val.chars().count() > 35 {
992                return Err(ValidationError::new(
993                    1002,
994                    "ctry_sub_dvsn exceeds the maximum length of 35".to_string(),
995                ));
996            }
997            let pattern = Regex::new(
998                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
999            )
1000            .unwrap();
1001            if !pattern.is_match(val) {
1002                return Err(ValidationError::new(
1003                    1005,
1004                    "ctry_sub_dvsn does not match the required pattern".to_string(),
1005                ));
1006            }
1007        }
1008        if let Some(ref val) = self.ctry {
1009            let pattern = Regex::new("[A-Z]{2,2}").unwrap();
1010            if !pattern.is_match(val) {
1011                return Err(ValidationError::new(
1012                    1005,
1013                    "ctry does not match the required pattern".to_string(),
1014                ));
1015            }
1016        }
1017        if let Some(ref vec) = self.adr_line {
1018            for item in vec {
1019                if item.chars().count() < 1 {
1020                    return Err(ValidationError::new(
1021                        1001,
1022                        "adr_line is shorter than the minimum length of 1".to_string(),
1023                    ));
1024                }
1025                if item.chars().count() > 70 {
1026                    return Err(ValidationError::new(
1027                        1002,
1028                        "adr_line exceeds the maximum length of 70".to_string(),
1029                    ));
1030                }
1031                let pattern = Regex::new(
1032                    "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1033                )
1034                .unwrap();
1035                if !pattern.is_match(&item) {
1036                    return Err(ValidationError::new(
1037                        1005,
1038                        "adr_line does not match the required pattern".to_string(),
1039                    ));
1040                }
1041            }
1042        }
1043        Ok(())
1044    }
1045}
1046
1047// ProxyAccountIdentification11: Identification used to indicate the account identification under another specified name.
1048#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1049pub struct ProxyAccountIdentification11 {
1050    #[serde(rename = "Tp", skip_serializing_if = "Option::is_none")]
1051    pub tp: Option<ProxyAccountType1Choice1>,
1052    #[serde(rename = "Id")]
1053    pub id: String,
1054}
1055
1056impl ProxyAccountIdentification11 {
1057    pub fn validate(&self) -> Result<(), ValidationError> {
1058        if let Some(ref val) = self.tp {
1059            val.validate()?
1060        }
1061        if self.id.chars().count() < 1 {
1062            return Err(ValidationError::new(
1063                1001,
1064                "id is shorter than the minimum length of 1".to_string(),
1065            ));
1066        }
1067        if self.id.chars().count() > 320 {
1068            return Err(ValidationError::new(
1069                1002,
1070                "id exceeds the maximum length of 320".to_string(),
1071            ));
1072        }
1073        let pattern =
1074            Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+")
1075                .unwrap();
1076        if !pattern.is_match(&self.id) {
1077            return Err(ValidationError::new(
1078                1005,
1079                "id does not match the required pattern".to_string(),
1080            ));
1081        }
1082        Ok(())
1083    }
1084}
1085
1086// ProxyAccountType1Choice1: Name of the identification scheme, in a free text form.
1087#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1088pub struct ProxyAccountType1Choice1 {
1089    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1090    pub cd: Option<String>,
1091    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1092    pub prtry: Option<String>,
1093}
1094
1095impl ProxyAccountType1Choice1 {
1096    pub fn validate(&self) -> Result<(), ValidationError> {
1097        if let Some(ref val) = self.cd {
1098            if val.chars().count() < 1 {
1099                return Err(ValidationError::new(
1100                    1001,
1101                    "cd is shorter than the minimum length of 1".to_string(),
1102                ));
1103            }
1104            if val.chars().count() > 4 {
1105                return Err(ValidationError::new(
1106                    1002,
1107                    "cd exceeds the maximum length of 4".to_string(),
1108                ));
1109            }
1110        }
1111        if let Some(ref val) = self.prtry {
1112            if val.chars().count() < 1 {
1113                return Err(ValidationError::new(
1114                    1001,
1115                    "prtry is shorter than the minimum length of 1".to_string(),
1116                ));
1117            }
1118            if val.chars().count() > 35 {
1119                return Err(ValidationError::new(
1120                    1002,
1121                    "prtry exceeds the maximum length of 35".to_string(),
1122                ));
1123            }
1124            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1125            if !pattern.is_match(val) {
1126                return Err(ValidationError::new(
1127                    1005,
1128                    "prtry does not match the required pattern".to_string(),
1129                ));
1130            }
1131        }
1132        Ok(())
1133    }
1134}
1135
1136// TotalCharges81: Indicates whether the total charges amount is a credit or a debit amount.
1137// Usage: A zero amount is considered to be a credit.
1138#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1139pub struct TotalCharges81 {
1140    #[serde(rename = "NbOfChrgsBrkdwnItms")]
1141    pub nb_of_chrgs_brkdwn_itms: String,
1142    #[serde(rename = "TtlChrgsAmt")]
1143    pub ttl_chrgs_amt: CBPRAmount,
1144    #[serde(rename = "CdtDbtInd")]
1145    pub cdt_dbt_ind: CreditDebitCode1,
1146}
1147
1148impl TotalCharges81 {
1149    pub fn validate(&self) -> Result<(), ValidationError> {
1150        let pattern = Regex::new("[0-9]{1,15}").unwrap();
1151        if !pattern.is_match(&self.nb_of_chrgs_brkdwn_itms) {
1152            return Err(ValidationError::new(
1153                1005,
1154                "nb_of_chrgs_brkdwn_itms does not match the required pattern".to_string(),
1155            ));
1156        }
1157        self.ttl_chrgs_amt.validate()?;
1158        self.cdt_dbt_ind.validate()?;
1159        Ok(())
1160    }
1161}
1162
1163// 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.
1164#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1165pub struct TransactionReferences71 {
1166    #[serde(rename = "MsgId", skip_serializing_if = "Option::is_none")]
1167    pub msg_id: Option<String>,
1168    #[serde(rename = "MsgNmId", skip_serializing_if = "Option::is_none")]
1169    pub msg_nm_id: Option<String>,
1170    #[serde(rename = "AcctSvcrRef", skip_serializing_if = "Option::is_none")]
1171    pub acct_svcr_ref: Option<String>,
1172    #[serde(rename = "PmtInfId", skip_serializing_if = "Option::is_none")]
1173    pub pmt_inf_id: Option<String>,
1174    #[serde(rename = "InstrId", skip_serializing_if = "Option::is_none")]
1175    pub instr_id: Option<String>,
1176    #[serde(rename = "EndToEndId", skip_serializing_if = "Option::is_none")]
1177    pub end_to_end_id: Option<String>,
1178    #[serde(rename = "UETR", skip_serializing_if = "Option::is_none")]
1179    pub uetr: Option<String>,
1180    #[serde(rename = "TxId", skip_serializing_if = "Option::is_none")]
1181    pub tx_id: Option<String>,
1182    #[serde(rename = "MndtId", skip_serializing_if = "Option::is_none")]
1183    pub mndt_id: Option<String>,
1184    #[serde(rename = "ChqNb", skip_serializing_if = "Option::is_none")]
1185    pub chq_nb: Option<String>,
1186    #[serde(rename = "AcctOwnrTxId", skip_serializing_if = "Option::is_none")]
1187    pub acct_ownr_tx_id: Option<String>,
1188    #[serde(rename = "AcctSvcrTxId", skip_serializing_if = "Option::is_none")]
1189    pub acct_svcr_tx_id: Option<String>,
1190    #[serde(rename = "PrcgId", skip_serializing_if = "Option::is_none")]
1191    pub prcg_id: Option<String>,
1192}
1193
1194impl TransactionReferences71 {
1195    pub fn validate(&self) -> Result<(), ValidationError> {
1196        if let Some(ref val) = self.msg_id {
1197            if val.chars().count() < 1 {
1198                return Err(ValidationError::new(
1199                    1001,
1200                    "msg_id is shorter than the minimum length of 1".to_string(),
1201                ));
1202            }
1203            if val.chars().count() > 35 {
1204                return Err(ValidationError::new(
1205                    1002,
1206                    "msg_id exceeds the maximum length of 35".to_string(),
1207                ));
1208            }
1209            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1210            if !pattern.is_match(val) {
1211                return Err(ValidationError::new(
1212                    1005,
1213                    "msg_id does not match the required pattern".to_string(),
1214                ));
1215            }
1216        }
1217        if let Some(ref val) = self.msg_nm_id {
1218            if val.chars().count() < 1 {
1219                return Err(ValidationError::new(
1220                    1001,
1221                    "msg_nm_id is shorter than the minimum length of 1".to_string(),
1222                ));
1223            }
1224            if val.chars().count() > 35 {
1225                return Err(ValidationError::new(
1226                    1002,
1227                    "msg_nm_id exceeds the maximum length of 35".to_string(),
1228                ));
1229            }
1230            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1231            if !pattern.is_match(val) {
1232                return Err(ValidationError::new(
1233                    1005,
1234                    "msg_nm_id does not match the required pattern".to_string(),
1235                ));
1236            }
1237        }
1238        if let Some(ref val) = self.acct_svcr_ref {
1239            if val.chars().count() < 1 {
1240                return Err(ValidationError::new(
1241                    1001,
1242                    "acct_svcr_ref is shorter than the minimum length of 1".to_string(),
1243                ));
1244            }
1245            if val.chars().count() > 35 {
1246                return Err(ValidationError::new(
1247                    1002,
1248                    "acct_svcr_ref exceeds the maximum length of 35".to_string(),
1249                ));
1250            }
1251            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1252            if !pattern.is_match(val) {
1253                return Err(ValidationError::new(
1254                    1005,
1255                    "acct_svcr_ref does not match the required pattern".to_string(),
1256                ));
1257            }
1258        }
1259        if let Some(ref val) = self.pmt_inf_id {
1260            if val.chars().count() < 1 {
1261                return Err(ValidationError::new(
1262                    1001,
1263                    "pmt_inf_id is shorter than the minimum length of 1".to_string(),
1264                ));
1265            }
1266            if val.chars().count() > 35 {
1267                return Err(ValidationError::new(
1268                    1002,
1269                    "pmt_inf_id exceeds the maximum length of 35".to_string(),
1270                ));
1271            }
1272            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1273            if !pattern.is_match(val) {
1274                return Err(ValidationError::new(
1275                    1005,
1276                    "pmt_inf_id does not match the required pattern".to_string(),
1277                ));
1278            }
1279        }
1280        if let Some(ref val) = self.instr_id {
1281            if val.chars().count() < 1 {
1282                return Err(ValidationError::new(
1283                    1001,
1284                    "instr_id is shorter than the minimum length of 1".to_string(),
1285                ));
1286            }
1287            if val.chars().count() > 16 {
1288                return Err(ValidationError::new(
1289                    1002,
1290                    "instr_id exceeds the maximum length of 16".to_string(),
1291                ));
1292            }
1293            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1294            if !pattern.is_match(val) {
1295                return Err(ValidationError::new(
1296                    1005,
1297                    "instr_id does not match the required pattern".to_string(),
1298                ));
1299            }
1300        }
1301        if let Some(ref val) = self.end_to_end_id {
1302            if val.chars().count() < 1 {
1303                return Err(ValidationError::new(
1304                    1001,
1305                    "end_to_end_id is shorter than the minimum length of 1".to_string(),
1306                ));
1307            }
1308            if val.chars().count() > 35 {
1309                return Err(ValidationError::new(
1310                    1002,
1311                    "end_to_end_id exceeds the maximum length of 35".to_string(),
1312                ));
1313            }
1314            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1315            if !pattern.is_match(val) {
1316                return Err(ValidationError::new(
1317                    1005,
1318                    "end_to_end_id does not match the required pattern".to_string(),
1319                ));
1320            }
1321        }
1322        if let Some(ref val) = self.uetr {
1323            let pattern =
1324                Regex::new("[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}")
1325                    .unwrap();
1326            if !pattern.is_match(val) {
1327                return Err(ValidationError::new(
1328                    1005,
1329                    "uetr does not match the required pattern".to_string(),
1330                ));
1331            }
1332        }
1333        if let Some(ref val) = self.tx_id {
1334            if val.chars().count() < 1 {
1335                return Err(ValidationError::new(
1336                    1001,
1337                    "tx_id is shorter than the minimum length of 1".to_string(),
1338                ));
1339            }
1340            if val.chars().count() > 35 {
1341                return Err(ValidationError::new(
1342                    1002,
1343                    "tx_id exceeds the maximum length of 35".to_string(),
1344                ));
1345            }
1346            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1347            if !pattern.is_match(val) {
1348                return Err(ValidationError::new(
1349                    1005,
1350                    "tx_id does not match the required pattern".to_string(),
1351                ));
1352            }
1353        }
1354        if let Some(ref val) = self.mndt_id {
1355            if val.chars().count() < 1 {
1356                return Err(ValidationError::new(
1357                    1001,
1358                    "mndt_id is shorter than the minimum length of 1".to_string(),
1359                ));
1360            }
1361            if val.chars().count() > 35 {
1362                return Err(ValidationError::new(
1363                    1002,
1364                    "mndt_id exceeds the maximum length of 35".to_string(),
1365                ));
1366            }
1367            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1368            if !pattern.is_match(val) {
1369                return Err(ValidationError::new(
1370                    1005,
1371                    "mndt_id does not match the required pattern".to_string(),
1372                ));
1373            }
1374        }
1375        if let Some(ref val) = self.chq_nb {
1376            if val.chars().count() < 1 {
1377                return Err(ValidationError::new(
1378                    1001,
1379                    "chq_nb is shorter than the minimum length of 1".to_string(),
1380                ));
1381            }
1382            if val.chars().count() > 35 {
1383                return Err(ValidationError::new(
1384                    1002,
1385                    "chq_nb exceeds the maximum length of 35".to_string(),
1386                ));
1387            }
1388            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1389            if !pattern.is_match(val) {
1390                return Err(ValidationError::new(
1391                    1005,
1392                    "chq_nb does not match the required pattern".to_string(),
1393                ));
1394            }
1395        }
1396        if let Some(ref val) = self.acct_ownr_tx_id {
1397            if val.chars().count() < 1 {
1398                return Err(ValidationError::new(
1399                    1001,
1400                    "acct_ownr_tx_id is shorter than the minimum length of 1".to_string(),
1401                ));
1402            }
1403            if val.chars().count() > 35 {
1404                return Err(ValidationError::new(
1405                    1002,
1406                    "acct_ownr_tx_id exceeds the maximum length of 35".to_string(),
1407                ));
1408            }
1409            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1410            if !pattern.is_match(val) {
1411                return Err(ValidationError::new(
1412                    1005,
1413                    "acct_ownr_tx_id does not match the required pattern".to_string(),
1414                ));
1415            }
1416        }
1417        if let Some(ref val) = self.acct_svcr_tx_id {
1418            if val.chars().count() < 1 {
1419                return Err(ValidationError::new(
1420                    1001,
1421                    "acct_svcr_tx_id is shorter than the minimum length of 1".to_string(),
1422                ));
1423            }
1424            if val.chars().count() > 35 {
1425                return Err(ValidationError::new(
1426                    1002,
1427                    "acct_svcr_tx_id exceeds the maximum length of 35".to_string(),
1428                ));
1429            }
1430            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1431            if !pattern.is_match(val) {
1432                return Err(ValidationError::new(
1433                    1005,
1434                    "acct_svcr_tx_id does not match the required pattern".to_string(),
1435                ));
1436            }
1437        }
1438        if let Some(ref val) = self.prcg_id {
1439            if val.chars().count() < 1 {
1440                return Err(ValidationError::new(
1441                    1001,
1442                    "prcg_id is shorter than the minimum length of 1".to_string(),
1443                ));
1444            }
1445            if val.chars().count() > 35 {
1446                return Err(ValidationError::new(
1447                    1002,
1448                    "prcg_id exceeds the maximum length of 35".to_string(),
1449                ));
1450            }
1451            let pattern = Regex::new("[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+").unwrap();
1452            if !pattern.is_match(val) {
1453                return Err(ValidationError::new(
1454                    1005,
1455                    "prcg_id does not match the required pattern".to_string(),
1456                ));
1457            }
1458        }
1459        Ok(())
1460    }
1461}