mx_message/document/
pacs_010_001_03_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
19use crate::parse_result::{ErrorCollector, ParserConfig};
20use crate::validation::{Validate, helpers};
21use serde::{Deserialize, Serialize};
22
23// AccountIdentification4Choice1: Unique identification of an account, as assigned by the account servicer, using an identification scheme.
24#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
25pub struct AccountIdentification4Choice1 {
26    #[serde(rename = "IBAN", skip_serializing_if = "Option::is_none")]
27    pub iban: Option<String>,
28    #[serde(rename = "Othr", skip_serializing_if = "Option::is_none")]
29    pub othr: Option<GenericAccountIdentification11>,
30}
31
32impl Validate for AccountIdentification4Choice1 {
33    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
34        if let Some(ref val) = self.iban {
35            helpers::validate_pattern(
36                val,
37                "IBAN",
38                "[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}",
39                &helpers::child_path(path, "IBAN"),
40                config,
41                collector,
42            );
43        }
44        if let Some(ref val) = self.othr
45            && config.validate_optional_fields
46        {
47            val.validate(&helpers::child_path(path, "Othr"), config, collector);
48        }
49    }
50}
51
52// AccountSchemeName1Choice1: Name of the identification scheme, in a free text form.
53#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
54pub struct AccountSchemeName1Choice1 {
55    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
56    pub cd: Option<String>,
57    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
58    pub prtry: Option<String>,
59}
60
61impl Validate for AccountSchemeName1Choice1 {
62    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
63        if let Some(ref val) = self.cd {
64            helpers::validate_length(
65                val,
66                "Cd",
67                Some(1),
68                Some(4),
69                &helpers::child_path(path, "Cd"),
70                config,
71                collector,
72            );
73        }
74        if let Some(ref val) = self.prtry {
75            helpers::validate_length(
76                val,
77                "Prtry",
78                Some(1),
79                Some(35),
80                &helpers::child_path(path, "Prtry"),
81                config,
82                collector,
83            );
84        }
85        if let Some(ref val) = self.prtry {
86            helpers::validate_pattern(
87                val,
88                "Prtry",
89                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
90                &helpers::child_path(path, "Prtry"),
91                config,
92                collector,
93            );
94        }
95    }
96}
97
98// ActiveCurrencyAndAmount: A number of monetary units specified in an active currency where the unit of currency is explicit and compliant with ISO 4217.
99#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
100pub struct ActiveCurrencyAndAmount {
101    #[serde(rename = "@Ccy")]
102    pub ccy: String,
103    #[serde(rename = "$value")]
104    pub value: f64,
105}
106
107impl Validate for ActiveCurrencyAndAmount {
108    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {}
109}
110
111// BranchAndFinancialInstitutionIdentification61: Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
112#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
113pub struct BranchAndFinancialInstitutionIdentification61 {
114    #[serde(rename = "FinInstnId")]
115    pub fin_instn_id: FinancialInstitutionIdentification181,
116}
117
118impl Validate for BranchAndFinancialInstitutionIdentification61 {
119    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
120        self.fin_instn_id
121            .validate(&helpers::child_path(path, "FinInstnId"), config, collector);
122    }
123}
124
125// BranchAndFinancialInstitutionIdentification62: Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
126#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
127pub struct BranchAndFinancialInstitutionIdentification62 {
128    #[serde(rename = "FinInstnId")]
129    pub fin_instn_id: FinancialInstitutionIdentification182,
130}
131
132impl Validate for BranchAndFinancialInstitutionIdentification62 {
133    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
134        self.fin_instn_id
135            .validate(&helpers::child_path(path, "FinInstnId"), config, collector);
136    }
137}
138
139// CashAccount381: Specifies an alternate assumed name for the identification of the account.
140#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
141pub struct CashAccount381 {
142    #[serde(rename = "Id")]
143    pub id: AccountIdentification4Choice1,
144    #[serde(rename = "Tp", skip_serializing_if = "Option::is_none")]
145    pub tp: Option<CashAccountType2Choice1>,
146    #[serde(rename = "Ccy", skip_serializing_if = "Option::is_none")]
147    pub ccy: Option<String>,
148    #[serde(rename = "Nm", skip_serializing_if = "Option::is_none")]
149    pub nm: Option<String>,
150    #[serde(rename = "Prxy", skip_serializing_if = "Option::is_none")]
151    pub prxy: Option<ProxyAccountIdentification11>,
152}
153
154impl Validate for CashAccount381 {
155    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
156        self.id
157            .validate(&helpers::child_path(path, "Id"), config, collector);
158        if let Some(ref val) = self.tp
159            && config.validate_optional_fields
160        {
161            val.validate(&helpers::child_path(path, "Tp"), config, collector);
162        }
163        if let Some(ref val) = self.ccy {
164            helpers::validate_pattern(
165                val,
166                "Ccy",
167                "[A-Z]{3,3}",
168                &helpers::child_path(path, "Ccy"),
169                config,
170                collector,
171            );
172        }
173        if let Some(ref val) = self.nm {
174            helpers::validate_length(
175                val,
176                "Nm",
177                Some(1),
178                Some(70),
179                &helpers::child_path(path, "Nm"),
180                config,
181                collector,
182            );
183        }
184        if let Some(ref val) = self.nm {
185            helpers::validate_pattern(
186                val,
187                "Nm",
188                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
189                &helpers::child_path(path, "Nm"),
190                config,
191                collector,
192            );
193        }
194        if let Some(ref val) = self.prxy
195            && config.validate_optional_fields
196        {
197            val.validate(&helpers::child_path(path, "Prxy"), config, collector);
198        }
199    }
200}
201
202// CashAccountType2Choice1: Nature or use of the account in a proprietary form.
203#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
204pub struct CashAccountType2Choice1 {
205    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
206    pub cd: Option<String>,
207    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
208    pub prtry: Option<String>,
209}
210
211impl Validate for CashAccountType2Choice1 {
212    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
213        if let Some(ref val) = self.cd {
214            helpers::validate_length(
215                val,
216                "Cd",
217                Some(1),
218                Some(4),
219                &helpers::child_path(path, "Cd"),
220                config,
221                collector,
222            );
223        }
224        if let Some(ref val) = self.prtry {
225            helpers::validate_length(
226                val,
227                "Prtry",
228                Some(1),
229                Some(35),
230                &helpers::child_path(path, "Prtry"),
231                config,
232                collector,
233            );
234        }
235        if let Some(ref val) = self.prtry {
236            helpers::validate_pattern(
237                val,
238                "Prtry",
239                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
240                &helpers::child_path(path, "Prtry"),
241                config,
242                collector,
243            );
244        }
245    }
246}
247
248// CategoryPurpose1Choice1: Category purpose, in a proprietary form.
249#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
250pub struct CategoryPurpose1Choice1 {
251    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
252    pub cd: Option<String>,
253    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
254    pub prtry: Option<String>,
255}
256
257impl Validate for CategoryPurpose1Choice1 {
258    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
259        if let Some(ref val) = self.cd {
260            helpers::validate_length(
261                val,
262                "Cd",
263                Some(1),
264                Some(4),
265                &helpers::child_path(path, "Cd"),
266                config,
267                collector,
268            );
269        }
270        if let Some(ref val) = self.prtry {
271            helpers::validate_length(
272                val,
273                "Prtry",
274                Some(1),
275                Some(35),
276                &helpers::child_path(path, "Prtry"),
277                config,
278                collector,
279            );
280        }
281        if let Some(ref val) = self.prtry {
282            helpers::validate_pattern(
283                val,
284                "Prtry",
285                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
286                &helpers::child_path(path, "Prtry"),
287                config,
288                collector,
289            );
290        }
291    }
292}
293
294// ClearingSystemIdentification2Choice1: Identification of a clearing system, in a coded form as published in an external list.
295#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
296pub struct ClearingSystemIdentification2Choice1 {
297    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
298    pub cd: Option<String>,
299}
300
301impl Validate for ClearingSystemIdentification2Choice1 {
302    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
303        if let Some(ref val) = self.cd {
304            helpers::validate_length(
305                val,
306                "Cd",
307                Some(1),
308                Some(5),
309                &helpers::child_path(path, "Cd"),
310                config,
311                collector,
312            );
313        }
314    }
315}
316
317// ClearingSystemMemberIdentification21: Identification of a member of a clearing system.
318#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
319pub struct ClearingSystemMemberIdentification21 {
320    #[serde(rename = "ClrSysId")]
321    pub clr_sys_id: ClearingSystemIdentification2Choice1,
322    #[serde(rename = "MmbId")]
323    pub mmb_id: String,
324}
325
326impl Validate for ClearingSystemMemberIdentification21 {
327    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
328        self.clr_sys_id
329            .validate(&helpers::child_path(path, "ClrSysId"), config, collector);
330        helpers::validate_length(
331            &self.mmb_id,
332            "MmbId",
333            Some(1),
334            Some(28),
335            &helpers::child_path(path, "MmbId"),
336            config,
337            collector,
338        );
339        helpers::validate_pattern(
340            &self.mmb_id,
341            "MmbId",
342            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
343            &helpers::child_path(path, "MmbId"),
344            config,
345            collector,
346        );
347    }
348}
349
350// CreditTransferTransaction381: Provides information on the individual debit transaction(s) included in the message.
351#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
352pub struct CreditTransferTransaction381 {
353    #[serde(rename = "CdtId")]
354    pub cdt_id: String,
355    #[serde(rename = "PmtTpInf", skip_serializing_if = "Option::is_none")]
356    pub pmt_tp_inf: Option<PaymentTypeInformation281>,
357    #[serde(rename = "InstgAgt")]
358    pub instg_agt: BranchAndFinancialInstitutionIdentification61,
359    #[serde(rename = "InstdAgt")]
360    pub instd_agt: BranchAndFinancialInstitutionIdentification61,
361    #[serde(rename = "IntrmyAgt1", skip_serializing_if = "Option::is_none")]
362    pub intrmy_agt1: Option<BranchAndFinancialInstitutionIdentification62>,
363    #[serde(rename = "IntrmyAgt1Acct", skip_serializing_if = "Option::is_none")]
364    pub intrmy_agt1_acct: Option<CashAccount381>,
365    #[serde(rename = "IntrmyAgt2", skip_serializing_if = "Option::is_none")]
366    pub intrmy_agt2: Option<BranchAndFinancialInstitutionIdentification62>,
367    #[serde(rename = "IntrmyAgt2Acct", skip_serializing_if = "Option::is_none")]
368    pub intrmy_agt2_acct: Option<CashAccount381>,
369    #[serde(rename = "IntrmyAgt3", skip_serializing_if = "Option::is_none")]
370    pub intrmy_agt3: Option<BranchAndFinancialInstitutionIdentification62>,
371    #[serde(rename = "IntrmyAgt3Acct", skip_serializing_if = "Option::is_none")]
372    pub intrmy_agt3_acct: Option<CashAccount381>,
373    #[serde(rename = "CdtrAgt", skip_serializing_if = "Option::is_none")]
374    pub cdtr_agt: Option<BranchAndFinancialInstitutionIdentification62>,
375    #[serde(rename = "CdtrAgtAcct", skip_serializing_if = "Option::is_none")]
376    pub cdtr_agt_acct: Option<CashAccount381>,
377    #[serde(rename = "Cdtr")]
378    pub cdtr: BranchAndFinancialInstitutionIdentification62,
379    #[serde(rename = "CdtrAcct", skip_serializing_if = "Option::is_none")]
380    pub cdtr_acct: Option<CashAccount381>,
381    #[serde(rename = "DrctDbtTxInf")]
382    pub drct_dbt_tx_inf: DirectDebitTransactionInformation251,
383}
384
385impl Validate for CreditTransferTransaction381 {
386    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
387        helpers::validate_length(
388            &self.cdt_id,
389            "CdtId",
390            Some(1),
391            Some(35),
392            &helpers::child_path(path, "CdtId"),
393            config,
394            collector,
395        );
396        helpers::validate_pattern(
397            &self.cdt_id,
398            "CdtId",
399            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
400            &helpers::child_path(path, "CdtId"),
401            config,
402            collector,
403        );
404        if let Some(ref val) = self.pmt_tp_inf
405            && config.validate_optional_fields
406        {
407            val.validate(&helpers::child_path(path, "PmtTpInf"), config, collector);
408        }
409        self.instg_agt
410            .validate(&helpers::child_path(path, "InstgAgt"), config, collector);
411        self.instd_agt
412            .validate(&helpers::child_path(path, "InstdAgt"), config, collector);
413        if let Some(ref val) = self.intrmy_agt1
414            && config.validate_optional_fields
415        {
416            val.validate(&helpers::child_path(path, "IntrmyAgt1"), config, collector);
417        }
418        if let Some(ref val) = self.intrmy_agt1_acct
419            && config.validate_optional_fields
420        {
421            val.validate(
422                &helpers::child_path(path, "IntrmyAgt1Acct"),
423                config,
424                collector,
425            );
426        }
427        if let Some(ref val) = self.intrmy_agt2
428            && config.validate_optional_fields
429        {
430            val.validate(&helpers::child_path(path, "IntrmyAgt2"), config, collector);
431        }
432        if let Some(ref val) = self.intrmy_agt2_acct
433            && config.validate_optional_fields
434        {
435            val.validate(
436                &helpers::child_path(path, "IntrmyAgt2Acct"),
437                config,
438                collector,
439            );
440        }
441        if let Some(ref val) = self.intrmy_agt3
442            && config.validate_optional_fields
443        {
444            val.validate(&helpers::child_path(path, "IntrmyAgt3"), config, collector);
445        }
446        if let Some(ref val) = self.intrmy_agt3_acct
447            && config.validate_optional_fields
448        {
449            val.validate(
450                &helpers::child_path(path, "IntrmyAgt3Acct"),
451                config,
452                collector,
453            );
454        }
455        if let Some(ref val) = self.cdtr_agt
456            && config.validate_optional_fields
457        {
458            val.validate(&helpers::child_path(path, "CdtrAgt"), config, collector);
459        }
460        if let Some(ref val) = self.cdtr_agt_acct
461            && config.validate_optional_fields
462        {
463            val.validate(&helpers::child_path(path, "CdtrAgtAcct"), config, collector);
464        }
465        self.cdtr
466            .validate(&helpers::child_path(path, "Cdtr"), config, collector);
467        if let Some(ref val) = self.cdtr_acct
468            && config.validate_optional_fields
469        {
470            val.validate(&helpers::child_path(path, "CdtrAcct"), config, collector);
471        }
472        self.drct_dbt_tx_inf.validate(
473            &helpers::child_path(path, "DrctDbtTxInf"),
474            config,
475            collector,
476        );
477    }
478}
479
480// DirectDebitTransactionInformation251: Information supplied to enable the matching of an entry with the items that the transfer is intended to settle, such as commercial invoices in an accounts' receivable system.
481#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
482pub struct DirectDebitTransactionInformation251 {
483    #[serde(rename = "PmtId")]
484    pub pmt_id: PaymentIdentification71,
485    #[serde(rename = "PmtTpInf", skip_serializing_if = "Option::is_none")]
486    pub pmt_tp_inf: Option<PaymentTypeInformation282>,
487    #[serde(rename = "IntrBkSttlmAmt")]
488    pub intr_bk_sttlm_amt: ActiveCurrencyAndAmount,
489    #[serde(rename = "IntrBkSttlmDt")]
490    pub intr_bk_sttlm_dt: String,
491    #[serde(rename = "SttlmTmReq", skip_serializing_if = "Option::is_none")]
492    pub sttlm_tm_req: Option<SettlementTimeRequest21>,
493    #[serde(rename = "Dbtr")]
494    pub dbtr: BranchAndFinancialInstitutionIdentification62,
495    #[serde(rename = "DbtrAcct", skip_serializing_if = "Option::is_none")]
496    pub dbtr_acct: Option<CashAccount381>,
497    #[serde(rename = "DbtrAgt", skip_serializing_if = "Option::is_none")]
498    pub dbtr_agt: Option<BranchAndFinancialInstitutionIdentification62>,
499    #[serde(rename = "DbtrAgtAcct", skip_serializing_if = "Option::is_none")]
500    pub dbtr_agt_acct: Option<CashAccount381>,
501    #[serde(rename = "InstrForDbtrAgt", skip_serializing_if = "Option::is_none")]
502    pub instr_for_dbtr_agt: Option<String>,
503    #[serde(rename = "Purp", skip_serializing_if = "Option::is_none")]
504    pub purp: Option<Purpose2Choice1>,
505    #[serde(rename = "RmtInf", skip_serializing_if = "Option::is_none")]
506    pub rmt_inf: Option<RemittanceInformation21>,
507}
508
509impl Validate for DirectDebitTransactionInformation251 {
510    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
511        self.pmt_id
512            .validate(&helpers::child_path(path, "PmtId"), config, collector);
513        if let Some(ref val) = self.pmt_tp_inf
514            && config.validate_optional_fields
515        {
516            val.validate(&helpers::child_path(path, "PmtTpInf"), config, collector);
517        }
518        self.intr_bk_sttlm_amt.validate(
519            &helpers::child_path(path, "IntrBkSttlmAmt"),
520            config,
521            collector,
522        );
523        if let Some(ref val) = self.sttlm_tm_req
524            && config.validate_optional_fields
525        {
526            val.validate(&helpers::child_path(path, "SttlmTmReq"), config, collector);
527        }
528        self.dbtr
529            .validate(&helpers::child_path(path, "Dbtr"), config, collector);
530        if let Some(ref val) = self.dbtr_acct
531            && config.validate_optional_fields
532        {
533            val.validate(&helpers::child_path(path, "DbtrAcct"), config, collector);
534        }
535        if let Some(ref val) = self.dbtr_agt
536            && config.validate_optional_fields
537        {
538            val.validate(&helpers::child_path(path, "DbtrAgt"), config, collector);
539        }
540        if let Some(ref val) = self.dbtr_agt_acct
541            && config.validate_optional_fields
542        {
543            val.validate(&helpers::child_path(path, "DbtrAgtAcct"), config, collector);
544        }
545        if let Some(ref val) = self.instr_for_dbtr_agt {
546            helpers::validate_length(
547                val,
548                "InstrForDbtrAgt",
549                Some(1),
550                Some(210),
551                &helpers::child_path(path, "InstrForDbtrAgt"),
552                config,
553                collector,
554            );
555        }
556        if let Some(ref val) = self.instr_for_dbtr_agt {
557            helpers::validate_pattern(
558                val,
559                "InstrForDbtrAgt",
560                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
561                &helpers::child_path(path, "InstrForDbtrAgt"),
562                config,
563                collector,
564            );
565        }
566        if let Some(ref val) = self.purp
567            && config.validate_optional_fields
568        {
569            val.validate(&helpers::child_path(path, "Purp"), config, collector);
570        }
571        if let Some(ref val) = self.rmt_inf
572            && config.validate_optional_fields
573        {
574            val.validate(&helpers::child_path(path, "RmtInf"), config, collector);
575        }
576    }
577}
578
579// FinancialInstitutionDirectDebitV03: Characteristics that apply to the credit side of the payment transaction(s) included in the message.
580#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
581pub struct FinancialInstitutionDirectDebitV03 {
582    #[serde(rename = "GrpHdr")]
583    pub grp_hdr: GroupHeader921,
584    #[serde(rename = "CdtInstr")]
585    pub cdt_instr: CreditTransferTransaction381,
586}
587
588impl Validate for FinancialInstitutionDirectDebitV03 {
589    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
590        self.grp_hdr
591            .validate(&helpers::child_path(path, "GrpHdr"), config, collector);
592        self.cdt_instr
593            .validate(&helpers::child_path(path, "CdtInstr"), config, collector);
594    }
595}
596
597// FinancialInstitutionIdentification181: Legal entity identifier of the financial institution.
598#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
599pub struct FinancialInstitutionIdentification181 {
600    #[serde(rename = "BICFI")]
601    pub bicfi: String,
602    #[serde(rename = "ClrSysMmbId", skip_serializing_if = "Option::is_none")]
603    pub clr_sys_mmb_id: Option<ClearingSystemMemberIdentification21>,
604    #[serde(rename = "LEI", skip_serializing_if = "Option::is_none")]
605    pub lei: Option<String>,
606}
607
608impl Validate for FinancialInstitutionIdentification181 {
609    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
610        helpers::validate_pattern(
611            &self.bicfi,
612            "BICFI",
613            "[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}",
614            &helpers::child_path(path, "BICFI"),
615            config,
616            collector,
617        );
618        if let Some(ref val) = self.clr_sys_mmb_id
619            && config.validate_optional_fields
620        {
621            val.validate(&helpers::child_path(path, "ClrSysMmbId"), config, collector);
622        }
623        if let Some(ref val) = self.lei {
624            helpers::validate_pattern(
625                val,
626                "LEI",
627                "[A-Z0-9]{18,18}[0-9]{2,2}",
628                &helpers::child_path(path, "LEI"),
629                config,
630                collector,
631            );
632        }
633    }
634}
635
636// FinancialInstitutionIdentification182: Information that locates and identifies a specific address, as defined by postal services.
637#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
638pub struct FinancialInstitutionIdentification182 {
639    #[serde(rename = "BICFI", skip_serializing_if = "Option::is_none")]
640    pub bicfi: Option<String>,
641    #[serde(rename = "ClrSysMmbId", skip_serializing_if = "Option::is_none")]
642    pub clr_sys_mmb_id: Option<ClearingSystemMemberIdentification21>,
643    #[serde(rename = "LEI", skip_serializing_if = "Option::is_none")]
644    pub lei: Option<String>,
645    #[serde(rename = "Nm", skip_serializing_if = "Option::is_none")]
646    pub nm: Option<String>,
647    #[serde(rename = "PstlAdr", skip_serializing_if = "Option::is_none")]
648    pub pstl_adr: Option<PostalAddress241>,
649}
650
651impl Validate for FinancialInstitutionIdentification182 {
652    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
653        if let Some(ref val) = self.bicfi {
654            helpers::validate_pattern(
655                val,
656                "BICFI",
657                "[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}",
658                &helpers::child_path(path, "BICFI"),
659                config,
660                collector,
661            );
662        }
663        if let Some(ref val) = self.clr_sys_mmb_id
664            && config.validate_optional_fields
665        {
666            val.validate(&helpers::child_path(path, "ClrSysMmbId"), config, collector);
667        }
668        if let Some(ref val) = self.lei {
669            helpers::validate_pattern(
670                val,
671                "LEI",
672                "[A-Z0-9]{18,18}[0-9]{2,2}",
673                &helpers::child_path(path, "LEI"),
674                config,
675                collector,
676            );
677        }
678        if let Some(ref val) = self.nm {
679            helpers::validate_length(
680                val,
681                "Nm",
682                Some(1),
683                Some(140),
684                &helpers::child_path(path, "Nm"),
685                config,
686                collector,
687            );
688        }
689        if let Some(ref val) = self.nm {
690            helpers::validate_pattern(
691                val,
692                "Nm",
693                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
694                &helpers::child_path(path, "Nm"),
695                config,
696                collector,
697            );
698        }
699        if let Some(ref val) = self.pstl_adr
700            && config.validate_optional_fields
701        {
702            val.validate(&helpers::child_path(path, "PstlAdr"), config, collector);
703        }
704    }
705}
706
707// GenericAccountIdentification11: Entity that assigns the identification.
708#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
709pub struct GenericAccountIdentification11 {
710    #[serde(rename = "Id")]
711    pub id: String,
712    #[serde(rename = "SchmeNm", skip_serializing_if = "Option::is_none")]
713    pub schme_nm: Option<AccountSchemeName1Choice1>,
714    #[serde(rename = "Issr", skip_serializing_if = "Option::is_none")]
715    pub issr: Option<String>,
716}
717
718impl Validate for GenericAccountIdentification11 {
719    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
720        helpers::validate_length(
721            &self.id,
722            "Id",
723            Some(1),
724            Some(34),
725            &helpers::child_path(path, "Id"),
726            config,
727            collector,
728        );
729        helpers::validate_pattern(
730            &self.id,
731            "Id",
732            "([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]*(/[0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ])?)*)",
733            &helpers::child_path(path, "Id"),
734            config,
735            collector,
736        );
737        if let Some(ref val) = self.schme_nm
738            && config.validate_optional_fields
739        {
740            val.validate(&helpers::child_path(path, "SchmeNm"), config, collector);
741        }
742        if let Some(ref val) = self.issr {
743            helpers::validate_length(
744                val,
745                "Issr",
746                Some(1),
747                Some(35),
748                &helpers::child_path(path, "Issr"),
749                config,
750                collector,
751            );
752        }
753        if let Some(ref val) = self.issr {
754            helpers::validate_pattern(
755                val,
756                "Issr",
757                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
758                &helpers::child_path(path, "Issr"),
759                config,
760                collector,
761            );
762        }
763    }
764}
765
766// GroupHeader921: Number of individual transactions contained in the message.
767#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
768pub struct GroupHeader921 {
769    #[serde(rename = "MsgId")]
770    pub msg_id: String,
771    #[serde(rename = "CreDtTm")]
772    pub cre_dt_tm: String,
773    #[serde(rename = "NbOfTxs")]
774    pub nb_of_txs: Max15NumericTextfixed,
775}
776
777impl Validate for GroupHeader921 {
778    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
779        helpers::validate_length(
780            &self.msg_id,
781            "MsgId",
782            Some(1),
783            Some(35),
784            &helpers::child_path(path, "MsgId"),
785            config,
786            collector,
787        );
788        helpers::validate_pattern(
789            &self.msg_id,
790            "MsgId",
791            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
792            &helpers::child_path(path, "MsgId"),
793            config,
794            collector,
795        );
796        helpers::validate_pattern(
797            &self.cre_dt_tm,
798            "CreDtTm",
799            ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
800            &helpers::child_path(path, "CreDtTm"),
801            config,
802            collector,
803        );
804        self.nb_of_txs
805            .validate(&helpers::child_path(path, "NbOfTxs"), config, collector);
806    }
807}
808
809// LocalInstrument2Choice1: Specifies the local instrument, as a proprietary code.
810#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
811pub struct LocalInstrument2Choice1 {
812    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
813    pub cd: Option<String>,
814    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
815    pub prtry: Option<String>,
816}
817
818impl Validate for LocalInstrument2Choice1 {
819    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
820        if let Some(ref val) = self.cd {
821            helpers::validate_length(
822                val,
823                "Cd",
824                Some(1),
825                Some(35),
826                &helpers::child_path(path, "Cd"),
827                config,
828                collector,
829            );
830        }
831        if let Some(ref val) = self.prtry {
832            helpers::validate_length(
833                val,
834                "Prtry",
835                Some(1),
836                Some(35),
837                &helpers::child_path(path, "Prtry"),
838                config,
839                collector,
840            );
841        }
842        if let Some(ref val) = self.prtry {
843            helpers::validate_pattern(
844                val,
845                "Prtry",
846                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
847                &helpers::child_path(path, "Prtry"),
848                config,
849                collector,
850            );
851        }
852    }
853}
854
855// Max15NumericText_fixed: 1
856#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
857pub enum Max15NumericTextfixed {
858    #[default]
859    #[serde(rename = "1")]
860    Code1,
861}
862
863impl Validate for Max15NumericTextfixed {
864    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
865        // Enum validation is typically empty
866    }
867}
868
869// PaymentIdentification71: Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
870#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
871pub struct PaymentIdentification71 {
872    #[serde(rename = "InstrId")]
873    pub instr_id: String,
874    #[serde(rename = "EndToEndId")]
875    pub end_to_end_id: String,
876    #[serde(rename = "TxId", skip_serializing_if = "Option::is_none")]
877    pub tx_id: Option<String>,
878    #[serde(rename = "UETR")]
879    pub uetr: String,
880    #[serde(rename = "ClrSysRef", skip_serializing_if = "Option::is_none")]
881    pub clr_sys_ref: Option<String>,
882}
883
884impl Validate for PaymentIdentification71 {
885    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
886        helpers::validate_length(
887            &self.instr_id,
888            "InstrId",
889            Some(1),
890            Some(35),
891            &helpers::child_path(path, "InstrId"),
892            config,
893            collector,
894        );
895        helpers::validate_pattern(
896            &self.instr_id,
897            "InstrId",
898            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
899            &helpers::child_path(path, "InstrId"),
900            config,
901            collector,
902        );
903        helpers::validate_length(
904            &self.end_to_end_id,
905            "EndToEndId",
906            Some(1),
907            Some(35),
908            &helpers::child_path(path, "EndToEndId"),
909            config,
910            collector,
911        );
912        helpers::validate_pattern(
913            &self.end_to_end_id,
914            "EndToEndId",
915            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
916            &helpers::child_path(path, "EndToEndId"),
917            config,
918            collector,
919        );
920        if let Some(ref val) = self.tx_id {
921            helpers::validate_length(
922                val,
923                "TxId",
924                Some(1),
925                Some(35),
926                &helpers::child_path(path, "TxId"),
927                config,
928                collector,
929            );
930        }
931        if let Some(ref val) = self.tx_id {
932            helpers::validate_pattern(
933                val,
934                "TxId",
935                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
936                &helpers::child_path(path, "TxId"),
937                config,
938                collector,
939            );
940        }
941        helpers::validate_pattern(
942            &self.uetr,
943            "UETR",
944            "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}",
945            &helpers::child_path(path, "UETR"),
946            config,
947            collector,
948        );
949        if let Some(ref val) = self.clr_sys_ref {
950            helpers::validate_length(
951                val,
952                "ClrSysRef",
953                Some(1),
954                Some(35),
955                &helpers::child_path(path, "ClrSysRef"),
956                config,
957                collector,
958            );
959        }
960        if let Some(ref val) = self.clr_sys_ref {
961            helpers::validate_pattern(
962                val,
963                "ClrSysRef",
964                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
965                &helpers::child_path(path, "ClrSysRef"),
966                config,
967                collector,
968            );
969        }
970    }
971}
972
973// PaymentTypeInformation281: Specifies the high level purpose of the instruction based on a set of pre-defined categories.
974// Usage: This is used by the initiating party to provide information concerning the processing of the payment. It is likely to trigger special processing by any of the agents involved in the payment chain.
975#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
976pub struct PaymentTypeInformation281 {
977    #[serde(rename = "InstrPrty", skip_serializing_if = "Option::is_none")]
978    pub instr_prty: Option<Priority2Code>,
979    #[serde(rename = "CtgyPurp", skip_serializing_if = "Option::is_none")]
980    pub ctgy_purp: Option<CategoryPurpose1Choice1>,
981}
982
983impl Validate for PaymentTypeInformation281 {
984    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
985        if let Some(ref val) = self.instr_prty
986            && config.validate_optional_fields
987        {
988            val.validate(&helpers::child_path(path, "InstrPrty"), config, collector);
989        }
990        if let Some(ref val) = self.ctgy_purp
991            && config.validate_optional_fields
992        {
993            val.validate(&helpers::child_path(path, "CtgyPurp"), config, collector);
994        }
995    }
996}
997
998// PaymentTypeInformation282: Specifies the high level purpose of the instruction based on a set of pre-defined categories.
999// Usage: This is used by the initiating party to provide information concerning the processing of the payment. It is likely to trigger special processing by any of the agents involved in the payment chain.
1000#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1001pub struct PaymentTypeInformation282 {
1002    #[serde(rename = "InstrPrty", skip_serializing_if = "Option::is_none")]
1003    pub instr_prty: Option<Priority2Code>,
1004    #[serde(rename = "SvcLvl", skip_serializing_if = "Option::is_none")]
1005    pub svc_lvl: Option<Vec<ServiceLevel8Choice1>>,
1006    #[serde(rename = "LclInstrm", skip_serializing_if = "Option::is_none")]
1007    pub lcl_instrm: Option<LocalInstrument2Choice1>,
1008    #[serde(rename = "CtgyPurp", skip_serializing_if = "Option::is_none")]
1009    pub ctgy_purp: Option<CategoryPurpose1Choice1>,
1010}
1011
1012impl Validate for PaymentTypeInformation282 {
1013    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1014        if let Some(ref val) = self.instr_prty
1015            && config.validate_optional_fields
1016        {
1017            val.validate(&helpers::child_path(path, "InstrPrty"), config, collector);
1018        }
1019        if let Some(ref vec) = self.svc_lvl
1020            && config.validate_optional_fields
1021        {
1022            for item in vec {
1023                item.validate(&helpers::child_path(path, "SvcLvl"), config, collector);
1024            }
1025        }
1026        if let Some(ref val) = self.lcl_instrm
1027            && config.validate_optional_fields
1028        {
1029            val.validate(&helpers::child_path(path, "LclInstrm"), config, collector);
1030        }
1031        if let Some(ref val) = self.ctgy_purp
1032            && config.validate_optional_fields
1033        {
1034            val.validate(&helpers::child_path(path, "CtgyPurp"), config, collector);
1035        }
1036    }
1037}
1038
1039// PostalAddress241: Information that locates and identifies a specific address, as defined by postal services, presented in free format text.
1040#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1041pub struct PostalAddress241 {
1042    #[serde(rename = "Dept", skip_serializing_if = "Option::is_none")]
1043    pub dept: Option<String>,
1044    #[serde(rename = "SubDept", skip_serializing_if = "Option::is_none")]
1045    pub sub_dept: Option<String>,
1046    #[serde(rename = "StrtNm", skip_serializing_if = "Option::is_none")]
1047    pub strt_nm: Option<String>,
1048    #[serde(rename = "BldgNb", skip_serializing_if = "Option::is_none")]
1049    pub bldg_nb: Option<String>,
1050    #[serde(rename = "BldgNm", skip_serializing_if = "Option::is_none")]
1051    pub bldg_nm: Option<String>,
1052    #[serde(rename = "Flr", skip_serializing_if = "Option::is_none")]
1053    pub flr: Option<String>,
1054    #[serde(rename = "PstBx", skip_serializing_if = "Option::is_none")]
1055    pub pst_bx: Option<String>,
1056    #[serde(rename = "Room", skip_serializing_if = "Option::is_none")]
1057    pub room: Option<String>,
1058    #[serde(rename = "PstCd", skip_serializing_if = "Option::is_none")]
1059    pub pst_cd: Option<String>,
1060    #[serde(rename = "TwnNm", skip_serializing_if = "Option::is_none")]
1061    pub twn_nm: Option<String>,
1062    #[serde(rename = "TwnLctnNm", skip_serializing_if = "Option::is_none")]
1063    pub twn_lctn_nm: Option<String>,
1064    #[serde(rename = "DstrctNm", skip_serializing_if = "Option::is_none")]
1065    pub dstrct_nm: Option<String>,
1066    #[serde(rename = "CtrySubDvsn", skip_serializing_if = "Option::is_none")]
1067    pub ctry_sub_dvsn: Option<String>,
1068    #[serde(rename = "Ctry", skip_serializing_if = "Option::is_none")]
1069    pub ctry: Option<String>,
1070    #[serde(rename = "AdrLine", skip_serializing_if = "Option::is_none")]
1071    pub adr_line: Option<Vec<String>>,
1072}
1073
1074impl Validate for PostalAddress241 {
1075    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1076        if let Some(ref val) = self.dept {
1077            helpers::validate_length(
1078                val,
1079                "Dept",
1080                Some(1),
1081                Some(70),
1082                &helpers::child_path(path, "Dept"),
1083                config,
1084                collector,
1085            );
1086        }
1087        if let Some(ref val) = self.dept {
1088            helpers::validate_pattern(
1089                val,
1090                "Dept",
1091                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1092                &helpers::child_path(path, "Dept"),
1093                config,
1094                collector,
1095            );
1096        }
1097        if let Some(ref val) = self.sub_dept {
1098            helpers::validate_length(
1099                val,
1100                "SubDept",
1101                Some(1),
1102                Some(70),
1103                &helpers::child_path(path, "SubDept"),
1104                config,
1105                collector,
1106            );
1107        }
1108        if let Some(ref val) = self.sub_dept {
1109            helpers::validate_pattern(
1110                val,
1111                "SubDept",
1112                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1113                &helpers::child_path(path, "SubDept"),
1114                config,
1115                collector,
1116            );
1117        }
1118        if let Some(ref val) = self.strt_nm {
1119            helpers::validate_length(
1120                val,
1121                "StrtNm",
1122                Some(1),
1123                Some(70),
1124                &helpers::child_path(path, "StrtNm"),
1125                config,
1126                collector,
1127            );
1128        }
1129        if let Some(ref val) = self.strt_nm {
1130            helpers::validate_pattern(
1131                val,
1132                "StrtNm",
1133                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1134                &helpers::child_path(path, "StrtNm"),
1135                config,
1136                collector,
1137            );
1138        }
1139        if let Some(ref val) = self.bldg_nb {
1140            helpers::validate_length(
1141                val,
1142                "BldgNb",
1143                Some(1),
1144                Some(16),
1145                &helpers::child_path(path, "BldgNb"),
1146                config,
1147                collector,
1148            );
1149        }
1150        if let Some(ref val) = self.bldg_nb {
1151            helpers::validate_pattern(
1152                val,
1153                "BldgNb",
1154                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1155                &helpers::child_path(path, "BldgNb"),
1156                config,
1157                collector,
1158            );
1159        }
1160        if let Some(ref val) = self.bldg_nm {
1161            helpers::validate_length(
1162                val,
1163                "BldgNm",
1164                Some(1),
1165                Some(35),
1166                &helpers::child_path(path, "BldgNm"),
1167                config,
1168                collector,
1169            );
1170        }
1171        if let Some(ref val) = self.bldg_nm {
1172            helpers::validate_pattern(
1173                val,
1174                "BldgNm",
1175                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1176                &helpers::child_path(path, "BldgNm"),
1177                config,
1178                collector,
1179            );
1180        }
1181        if let Some(ref val) = self.flr {
1182            helpers::validate_length(
1183                val,
1184                "Flr",
1185                Some(1),
1186                Some(70),
1187                &helpers::child_path(path, "Flr"),
1188                config,
1189                collector,
1190            );
1191        }
1192        if let Some(ref val) = self.flr {
1193            helpers::validate_pattern(
1194                val,
1195                "Flr",
1196                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1197                &helpers::child_path(path, "Flr"),
1198                config,
1199                collector,
1200            );
1201        }
1202        if let Some(ref val) = self.pst_bx {
1203            helpers::validate_length(
1204                val,
1205                "PstBx",
1206                Some(1),
1207                Some(16),
1208                &helpers::child_path(path, "PstBx"),
1209                config,
1210                collector,
1211            );
1212        }
1213        if let Some(ref val) = self.pst_bx {
1214            helpers::validate_pattern(
1215                val,
1216                "PstBx",
1217                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1218                &helpers::child_path(path, "PstBx"),
1219                config,
1220                collector,
1221            );
1222        }
1223        if let Some(ref val) = self.room {
1224            helpers::validate_length(
1225                val,
1226                "Room",
1227                Some(1),
1228                Some(70),
1229                &helpers::child_path(path, "Room"),
1230                config,
1231                collector,
1232            );
1233        }
1234        if let Some(ref val) = self.room {
1235            helpers::validate_pattern(
1236                val,
1237                "Room",
1238                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1239                &helpers::child_path(path, "Room"),
1240                config,
1241                collector,
1242            );
1243        }
1244        if let Some(ref val) = self.pst_cd {
1245            helpers::validate_length(
1246                val,
1247                "PstCd",
1248                Some(1),
1249                Some(16),
1250                &helpers::child_path(path, "PstCd"),
1251                config,
1252                collector,
1253            );
1254        }
1255        if let Some(ref val) = self.pst_cd {
1256            helpers::validate_pattern(
1257                val,
1258                "PstCd",
1259                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1260                &helpers::child_path(path, "PstCd"),
1261                config,
1262                collector,
1263            );
1264        }
1265        if let Some(ref val) = self.twn_nm {
1266            helpers::validate_length(
1267                val,
1268                "TwnNm",
1269                Some(1),
1270                Some(35),
1271                &helpers::child_path(path, "TwnNm"),
1272                config,
1273                collector,
1274            );
1275        }
1276        if let Some(ref val) = self.twn_nm {
1277            helpers::validate_pattern(
1278                val,
1279                "TwnNm",
1280                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1281                &helpers::child_path(path, "TwnNm"),
1282                config,
1283                collector,
1284            );
1285        }
1286        if let Some(ref val) = self.twn_lctn_nm {
1287            helpers::validate_length(
1288                val,
1289                "TwnLctnNm",
1290                Some(1),
1291                Some(35),
1292                &helpers::child_path(path, "TwnLctnNm"),
1293                config,
1294                collector,
1295            );
1296        }
1297        if let Some(ref val) = self.twn_lctn_nm {
1298            helpers::validate_pattern(
1299                val,
1300                "TwnLctnNm",
1301                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1302                &helpers::child_path(path, "TwnLctnNm"),
1303                config,
1304                collector,
1305            );
1306        }
1307        if let Some(ref val) = self.dstrct_nm {
1308            helpers::validate_length(
1309                val,
1310                "DstrctNm",
1311                Some(1),
1312                Some(35),
1313                &helpers::child_path(path, "DstrctNm"),
1314                config,
1315                collector,
1316            );
1317        }
1318        if let Some(ref val) = self.dstrct_nm {
1319            helpers::validate_pattern(
1320                val,
1321                "DstrctNm",
1322                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1323                &helpers::child_path(path, "DstrctNm"),
1324                config,
1325                collector,
1326            );
1327        }
1328        if let Some(ref val) = self.ctry_sub_dvsn {
1329            helpers::validate_length(
1330                val,
1331                "CtrySubDvsn",
1332                Some(1),
1333                Some(35),
1334                &helpers::child_path(path, "CtrySubDvsn"),
1335                config,
1336                collector,
1337            );
1338        }
1339        if let Some(ref val) = self.ctry_sub_dvsn {
1340            helpers::validate_pattern(
1341                val,
1342                "CtrySubDvsn",
1343                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1344                &helpers::child_path(path, "CtrySubDvsn"),
1345                config,
1346                collector,
1347            );
1348        }
1349        if let Some(ref val) = self.ctry {
1350            helpers::validate_pattern(
1351                val,
1352                "Ctry",
1353                "[A-Z]{2,2}",
1354                &helpers::child_path(path, "Ctry"),
1355                config,
1356                collector,
1357            );
1358        }
1359        if let Some(ref vec) = self.adr_line {
1360            for item in vec {
1361                helpers::validate_length(
1362                    item,
1363                    "AdrLine",
1364                    Some(1),
1365                    Some(70),
1366                    &helpers::child_path(path, "AdrLine"),
1367                    config,
1368                    collector,
1369                );
1370            }
1371        }
1372        if let Some(ref vec) = self.adr_line {
1373            for item in vec {
1374                helpers::validate_pattern(
1375                    item,
1376                    "AdrLine",
1377                    "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1378                    &helpers::child_path(path, "AdrLine"),
1379                    config,
1380                    collector,
1381                );
1382            }
1383        }
1384    }
1385}
1386
1387// Priority2Code: Priority level is normal.
1388#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1389pub enum Priority2Code {
1390    #[default]
1391    #[serde(rename = "HIGH")]
1392    CodeHIGH,
1393    #[serde(rename = "NORM")]
1394    CodeNORM,
1395}
1396
1397impl Validate for Priority2Code {
1398    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
1399        // Enum validation is typically empty
1400    }
1401}
1402
1403// ProxyAccountIdentification11: Identification used to indicate the account identification under another specified name.
1404#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1405pub struct ProxyAccountIdentification11 {
1406    #[serde(rename = "Tp", skip_serializing_if = "Option::is_none")]
1407    pub tp: Option<ProxyAccountType1Choice1>,
1408    #[serde(rename = "Id")]
1409    pub id: String,
1410}
1411
1412impl Validate for ProxyAccountIdentification11 {
1413    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1414        if let Some(ref val) = self.tp
1415            && config.validate_optional_fields
1416        {
1417            val.validate(&helpers::child_path(path, "Tp"), config, collector);
1418        }
1419        helpers::validate_length(
1420            &self.id,
1421            "Id",
1422            Some(1),
1423            Some(320),
1424            &helpers::child_path(path, "Id"),
1425            config,
1426            collector,
1427        );
1428        helpers::validate_pattern(
1429            &self.id,
1430            "Id",
1431            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1432            &helpers::child_path(path, "Id"),
1433            config,
1434            collector,
1435        );
1436    }
1437}
1438
1439// ProxyAccountType1Choice1: Name of the identification scheme, in a free text form.
1440#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1441pub struct ProxyAccountType1Choice1 {
1442    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1443    pub cd: Option<String>,
1444    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1445    pub prtry: Option<String>,
1446}
1447
1448impl Validate for ProxyAccountType1Choice1 {
1449    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1450        if let Some(ref val) = self.cd {
1451            helpers::validate_length(
1452                val,
1453                "Cd",
1454                Some(1),
1455                Some(4),
1456                &helpers::child_path(path, "Cd"),
1457                config,
1458                collector,
1459            );
1460        }
1461        if let Some(ref val) = self.prtry {
1462            helpers::validate_length(
1463                val,
1464                "Prtry",
1465                Some(1),
1466                Some(35),
1467                &helpers::child_path(path, "Prtry"),
1468                config,
1469                collector,
1470            );
1471        }
1472        if let Some(ref val) = self.prtry {
1473            helpers::validate_pattern(
1474                val,
1475                "Prtry",
1476                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1477                &helpers::child_path(path, "Prtry"),
1478                config,
1479                collector,
1480            );
1481        }
1482    }
1483}
1484
1485// Purpose2Choice1: Purpose, in a proprietary form.
1486#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1487pub struct Purpose2Choice1 {
1488    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1489    pub cd: Option<String>,
1490    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1491    pub prtry: Option<String>,
1492}
1493
1494impl Validate for Purpose2Choice1 {
1495    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1496        if let Some(ref val) = self.cd {
1497            helpers::validate_length(
1498                val,
1499                "Cd",
1500                Some(1),
1501                Some(4),
1502                &helpers::child_path(path, "Cd"),
1503                config,
1504                collector,
1505            );
1506        }
1507        if let Some(ref val) = self.prtry {
1508            helpers::validate_length(
1509                val,
1510                "Prtry",
1511                Some(1),
1512                Some(35),
1513                &helpers::child_path(path, "Prtry"),
1514                config,
1515                collector,
1516            );
1517        }
1518        if let Some(ref val) = self.prtry {
1519            helpers::validate_pattern(
1520                val,
1521                "Prtry",
1522                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1523                &helpers::child_path(path, "Prtry"),
1524                config,
1525                collector,
1526            );
1527        }
1528    }
1529}
1530
1531// RemittanceInformation21: Information supplied to enable the matching of an entry with the items that the transfer is intended to settle, for example, commercial invoices in an accounts' receivable system in an unstructured form.
1532#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1533pub struct RemittanceInformation21 {
1534    #[serde(rename = "Ustrd")]
1535    pub ustrd: String,
1536}
1537
1538impl Validate for RemittanceInformation21 {
1539    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1540        helpers::validate_length(
1541            &self.ustrd,
1542            "Ustrd",
1543            Some(1),
1544            Some(140),
1545            &helpers::child_path(path, "Ustrd"),
1546            config,
1547            collector,
1548        );
1549        helpers::validate_pattern(
1550            &self.ustrd,
1551            "Ustrd",
1552            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1553            &helpers::child_path(path, "Ustrd"),
1554            config,
1555            collector,
1556        );
1557    }
1558}
1559
1560// ServiceLevel8Choice1: Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
1561#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1562pub struct ServiceLevel8Choice1 {
1563    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1564    pub cd: Option<String>,
1565    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1566    pub prtry: Option<String>,
1567}
1568
1569impl Validate for ServiceLevel8Choice1 {
1570    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1571        if let Some(ref val) = self.cd {
1572            helpers::validate_length(
1573                val,
1574                "Cd",
1575                Some(1),
1576                Some(4),
1577                &helpers::child_path(path, "Cd"),
1578                config,
1579                collector,
1580            );
1581        }
1582        if let Some(ref val) = self.prtry {
1583            helpers::validate_length(
1584                val,
1585                "Prtry",
1586                Some(1),
1587                Some(35),
1588                &helpers::child_path(path, "Prtry"),
1589                config,
1590                collector,
1591            );
1592        }
1593        if let Some(ref val) = self.prtry {
1594            helpers::validate_pattern(
1595                val,
1596                "Prtry",
1597                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1598                &helpers::child_path(path, "Prtry"),
1599                config,
1600                collector,
1601            );
1602        }
1603    }
1604}
1605
1606// SettlementTimeRequest21: Time by when the payment must be settled to avoid rejection.
1607#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1608pub struct SettlementTimeRequest21 {
1609    #[serde(rename = "CLSTm", skip_serializing_if = "Option::is_none")]
1610    pub cls_tm: Option<String>,
1611    #[serde(rename = "TillTm", skip_serializing_if = "Option::is_none")]
1612    pub till_tm: Option<String>,
1613    #[serde(rename = "FrTm", skip_serializing_if = "Option::is_none")]
1614    pub fr_tm: Option<String>,
1615    #[serde(rename = "RjctTm", skip_serializing_if = "Option::is_none")]
1616    pub rjct_tm: Option<String>,
1617}
1618
1619impl Validate for SettlementTimeRequest21 {
1620    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1621        if let Some(ref val) = self.cls_tm {
1622            helpers::validate_pattern(
1623                val,
1624                "CLSTm",
1625                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1626                &helpers::child_path(path, "CLSTm"),
1627                config,
1628                collector,
1629            );
1630        }
1631        if let Some(ref val) = self.till_tm {
1632            helpers::validate_pattern(
1633                val,
1634                "TillTm",
1635                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1636                &helpers::child_path(path, "TillTm"),
1637                config,
1638                collector,
1639            );
1640        }
1641        if let Some(ref val) = self.fr_tm {
1642            helpers::validate_pattern(
1643                val,
1644                "FrTm",
1645                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1646                &helpers::child_path(path, "FrTm"),
1647                config,
1648                collector,
1649            );
1650        }
1651        if let Some(ref val) = self.rjct_tm {
1652            helpers::validate_pattern(
1653                val,
1654                "RjctTm",
1655                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1656                &helpers::child_path(path, "RjctTm"),
1657                config,
1658                collector,
1659            );
1660        }
1661    }
1662}