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