mx_message/document/
pacs_009_001_08_adv.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// BranchAndFinancialInstitutionIdentification61: Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
99#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
100pub struct BranchAndFinancialInstitutionIdentification61 {
101    #[serde(rename = "FinInstnId")]
102    pub fin_instn_id: FinancialInstitutionIdentification181,
103}
104
105impl Validate for BranchAndFinancialInstitutionIdentification61 {
106    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
107        self.fin_instn_id
108            .validate(&helpers::child_path(path, "FinInstnId"), config, collector);
109    }
110}
111
112// BranchAndFinancialInstitutionIdentification62: Unique and unambiguous identification of a financial institution, as assigned under an internationally recognised or proprietary identification scheme.
113#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
114pub struct BranchAndFinancialInstitutionIdentification62 {
115    #[serde(rename = "FinInstnId")]
116    pub fin_instn_id: FinancialInstitutionIdentification182,
117}
118
119impl Validate for BranchAndFinancialInstitutionIdentification62 {
120    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
121        self.fin_instn_id
122            .validate(&helpers::child_path(path, "FinInstnId"), config, collector);
123    }
124}
125
126// CBPRAmount: CBPR_Amount
127#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
128pub struct CBPRAmount {
129    #[serde(rename = "@Ccy")]
130    pub ccy: String,
131    #[serde(rename = "$value")]
132    pub value: f64,
133}
134
135impl Validate for CBPRAmount {
136    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {}
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// ClearingChannel2Code: Payment through internal book transfer.
295#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
296pub enum ClearingChannel2Code {
297    #[default]
298    #[serde(rename = "RTGS")]
299    CodeRTGS,
300    #[serde(rename = "RTNS")]
301    CodeRTNS,
302    #[serde(rename = "MPNS")]
303    CodeMPNS,
304    #[serde(rename = "BOOK")]
305    CodeBOOK,
306}
307
308impl Validate for ClearingChannel2Code {
309    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
310        // Enum validation is typically empty
311    }
312}
313
314// ClearingSystemIdentification2Choice1: Identification of a clearing system, in a coded form as published in an external list.
315#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
316pub struct ClearingSystemIdentification2Choice1 {
317    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
318    pub cd: Option<String>,
319}
320
321impl Validate for ClearingSystemIdentification2Choice1 {
322    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
323        if let Some(ref val) = self.cd {
324            helpers::validate_length(
325                val,
326                "Cd",
327                Some(1),
328                Some(5),
329                &helpers::child_path(path, "Cd"),
330                config,
331                collector,
332            );
333        }
334    }
335}
336
337// ClearingSystemMemberIdentification21: Identification of a member of a clearing system.
338#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
339pub struct ClearingSystemMemberIdentification21 {
340    #[serde(rename = "ClrSysId")]
341    pub clr_sys_id: ClearingSystemIdentification2Choice1,
342    #[serde(rename = "MmbId")]
343    pub mmb_id: String,
344}
345
346impl Validate for ClearingSystemMemberIdentification21 {
347    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
348        self.clr_sys_id
349            .validate(&helpers::child_path(path, "ClrSysId"), config, collector);
350        helpers::validate_length(
351            &self.mmb_id,
352            "MmbId",
353            Some(1),
354            Some(28),
355            &helpers::child_path(path, "MmbId"),
356            config,
357            collector,
358        );
359        helpers::validate_pattern(
360            &self.mmb_id,
361            "MmbId",
362            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
363            &helpers::child_path(path, "MmbId"),
364            config,
365            collector,
366        );
367    }
368}
369
370// CreditTransferTransaction361: 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.
371#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
372pub struct CreditTransferTransaction361 {
373    #[serde(rename = "PmtId")]
374    pub pmt_id: PaymentIdentification71,
375    #[serde(rename = "PmtTpInf", skip_serializing_if = "Option::is_none")]
376    pub pmt_tp_inf: Option<PaymentTypeInformation281>,
377    #[serde(rename = "IntrBkSttlmAmt")]
378    pub intr_bk_sttlm_amt: CBPRAmount,
379    #[serde(rename = "IntrBkSttlmDt")]
380    pub intr_bk_sttlm_dt: String,
381    #[serde(rename = "SttlmPrty", skip_serializing_if = "Option::is_none")]
382    pub sttlm_prty: Option<Priority3Code>,
383    #[serde(rename = "SttlmTmIndctn", skip_serializing_if = "Option::is_none")]
384    pub sttlm_tm_indctn: Option<SettlementDateTimeIndication11>,
385    #[serde(rename = "SttlmTmReq", skip_serializing_if = "Option::is_none")]
386    pub sttlm_tm_req: Option<SettlementTimeRequest21>,
387    #[serde(rename = "PrvsInstgAgt1", skip_serializing_if = "Option::is_none")]
388    pub prvs_instg_agt1: Option<BranchAndFinancialInstitutionIdentification61>,
389    #[serde(rename = "PrvsInstgAgt1Acct", skip_serializing_if = "Option::is_none")]
390    pub prvs_instg_agt1_acct: Option<CashAccount381>,
391    #[serde(rename = "PrvsInstgAgt2", skip_serializing_if = "Option::is_none")]
392    pub prvs_instg_agt2: Option<BranchAndFinancialInstitutionIdentification61>,
393    #[serde(rename = "PrvsInstgAgt2Acct", skip_serializing_if = "Option::is_none")]
394    pub prvs_instg_agt2_acct: Option<CashAccount381>,
395    #[serde(rename = "PrvsInstgAgt3", skip_serializing_if = "Option::is_none")]
396    pub prvs_instg_agt3: Option<BranchAndFinancialInstitutionIdentification61>,
397    #[serde(rename = "PrvsInstgAgt3Acct", skip_serializing_if = "Option::is_none")]
398    pub prvs_instg_agt3_acct: Option<CashAccount381>,
399    #[serde(rename = "InstgAgt")]
400    pub instg_agt: BranchAndFinancialInstitutionIdentification62,
401    #[serde(rename = "InstdAgt")]
402    pub instd_agt: BranchAndFinancialInstitutionIdentification62,
403    #[serde(rename = "IntrmyAgt1", skip_serializing_if = "Option::is_none")]
404    pub intrmy_agt1: Option<BranchAndFinancialInstitutionIdentification61>,
405    #[serde(rename = "IntrmyAgt1Acct", skip_serializing_if = "Option::is_none")]
406    pub intrmy_agt1_acct: Option<CashAccount381>,
407    #[serde(rename = "IntrmyAgt2", skip_serializing_if = "Option::is_none")]
408    pub intrmy_agt2: Option<BranchAndFinancialInstitutionIdentification61>,
409    #[serde(rename = "IntrmyAgt2Acct", skip_serializing_if = "Option::is_none")]
410    pub intrmy_agt2_acct: Option<CashAccount381>,
411    #[serde(rename = "IntrmyAgt3", skip_serializing_if = "Option::is_none")]
412    pub intrmy_agt3: Option<BranchAndFinancialInstitutionIdentification61>,
413    #[serde(rename = "IntrmyAgt3Acct", skip_serializing_if = "Option::is_none")]
414    pub intrmy_agt3_acct: Option<CashAccount381>,
415    #[serde(rename = "Dbtr")]
416    pub dbtr: BranchAndFinancialInstitutionIdentification61,
417    #[serde(rename = "DbtrAcct", skip_serializing_if = "Option::is_none")]
418    pub dbtr_acct: Option<CashAccount381>,
419    #[serde(rename = "DbtrAgt", skip_serializing_if = "Option::is_none")]
420    pub dbtr_agt: Option<BranchAndFinancialInstitutionIdentification61>,
421    #[serde(rename = "DbtrAgtAcct", skip_serializing_if = "Option::is_none")]
422    pub dbtr_agt_acct: Option<CashAccount381>,
423    #[serde(rename = "CdtrAgt", skip_serializing_if = "Option::is_none")]
424    pub cdtr_agt: Option<BranchAndFinancialInstitutionIdentification61>,
425    #[serde(rename = "CdtrAgtAcct", skip_serializing_if = "Option::is_none")]
426    pub cdtr_agt_acct: Option<CashAccount381>,
427    #[serde(rename = "Cdtr")]
428    pub cdtr: BranchAndFinancialInstitutionIdentification61,
429    #[serde(rename = "CdtrAcct", skip_serializing_if = "Option::is_none")]
430    pub cdtr_acct: Option<CashAccount381>,
431    #[serde(rename = "InstrForCdtrAgt", skip_serializing_if = "Option::is_none")]
432    pub instr_for_cdtr_agt: Option<Vec<InstructionForCreditorAgent21>>,
433    #[serde(rename = "InstrForNxtAgt", skip_serializing_if = "Option::is_none")]
434    pub instr_for_nxt_agt: Option<Vec<InstructionForNextAgent11>>,
435    #[serde(rename = "Purp", skip_serializing_if = "Option::is_none")]
436    pub purp: Option<Purpose2Choice1>,
437    #[serde(rename = "RmtInf", skip_serializing_if = "Option::is_none")]
438    pub rmt_inf: Option<RemittanceInformation21>,
439}
440
441impl Validate for CreditTransferTransaction361 {
442    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
443        self.pmt_id
444            .validate(&helpers::child_path(path, "PmtId"), config, collector);
445        if let Some(ref val) = self.pmt_tp_inf
446            && config.validate_optional_fields
447        {
448            val.validate(&helpers::child_path(path, "PmtTpInf"), config, collector);
449        }
450        self.intr_bk_sttlm_amt.validate(
451            &helpers::child_path(path, "IntrBkSttlmAmt"),
452            config,
453            collector,
454        );
455        if let Some(ref val) = self.sttlm_prty
456            && config.validate_optional_fields
457        {
458            val.validate(&helpers::child_path(path, "SttlmPrty"), config, collector);
459        }
460        if let Some(ref val) = self.sttlm_tm_indctn
461            && config.validate_optional_fields
462        {
463            val.validate(
464                &helpers::child_path(path, "SttlmTmIndctn"),
465                config,
466                collector,
467            );
468        }
469        if let Some(ref val) = self.sttlm_tm_req
470            && config.validate_optional_fields
471        {
472            val.validate(&helpers::child_path(path, "SttlmTmReq"), config, collector);
473        }
474        if let Some(ref val) = self.prvs_instg_agt1
475            && config.validate_optional_fields
476        {
477            val.validate(
478                &helpers::child_path(path, "PrvsInstgAgt1"),
479                config,
480                collector,
481            );
482        }
483        if let Some(ref val) = self.prvs_instg_agt1_acct
484            && config.validate_optional_fields
485        {
486            val.validate(
487                &helpers::child_path(path, "PrvsInstgAgt1Acct"),
488                config,
489                collector,
490            );
491        }
492        if let Some(ref val) = self.prvs_instg_agt2
493            && config.validate_optional_fields
494        {
495            val.validate(
496                &helpers::child_path(path, "PrvsInstgAgt2"),
497                config,
498                collector,
499            );
500        }
501        if let Some(ref val) = self.prvs_instg_agt2_acct
502            && config.validate_optional_fields
503        {
504            val.validate(
505                &helpers::child_path(path, "PrvsInstgAgt2Acct"),
506                config,
507                collector,
508            );
509        }
510        if let Some(ref val) = self.prvs_instg_agt3
511            && config.validate_optional_fields
512        {
513            val.validate(
514                &helpers::child_path(path, "PrvsInstgAgt3"),
515                config,
516                collector,
517            );
518        }
519        if let Some(ref val) = self.prvs_instg_agt3_acct
520            && config.validate_optional_fields
521        {
522            val.validate(
523                &helpers::child_path(path, "PrvsInstgAgt3Acct"),
524                config,
525                collector,
526            );
527        }
528        self.instg_agt
529            .validate(&helpers::child_path(path, "InstgAgt"), config, collector);
530        self.instd_agt
531            .validate(&helpers::child_path(path, "InstdAgt"), config, collector);
532        if let Some(ref val) = self.intrmy_agt1
533            && config.validate_optional_fields
534        {
535            val.validate(&helpers::child_path(path, "IntrmyAgt1"), config, collector);
536        }
537        if let Some(ref val) = self.intrmy_agt1_acct
538            && config.validate_optional_fields
539        {
540            val.validate(
541                &helpers::child_path(path, "IntrmyAgt1Acct"),
542                config,
543                collector,
544            );
545        }
546        if let Some(ref val) = self.intrmy_agt2
547            && config.validate_optional_fields
548        {
549            val.validate(&helpers::child_path(path, "IntrmyAgt2"), config, collector);
550        }
551        if let Some(ref val) = self.intrmy_agt2_acct
552            && config.validate_optional_fields
553        {
554            val.validate(
555                &helpers::child_path(path, "IntrmyAgt2Acct"),
556                config,
557                collector,
558            );
559        }
560        if let Some(ref val) = self.intrmy_agt3
561            && config.validate_optional_fields
562        {
563            val.validate(&helpers::child_path(path, "IntrmyAgt3"), config, collector);
564        }
565        if let Some(ref val) = self.intrmy_agt3_acct
566            && config.validate_optional_fields
567        {
568            val.validate(
569                &helpers::child_path(path, "IntrmyAgt3Acct"),
570                config,
571                collector,
572            );
573        }
574        self.dbtr
575            .validate(&helpers::child_path(path, "Dbtr"), config, collector);
576        if let Some(ref val) = self.dbtr_acct
577            && config.validate_optional_fields
578        {
579            val.validate(&helpers::child_path(path, "DbtrAcct"), config, collector);
580        }
581        if let Some(ref val) = self.dbtr_agt
582            && config.validate_optional_fields
583        {
584            val.validate(&helpers::child_path(path, "DbtrAgt"), config, collector);
585        }
586        if let Some(ref val) = self.dbtr_agt_acct
587            && config.validate_optional_fields
588        {
589            val.validate(&helpers::child_path(path, "DbtrAgtAcct"), config, collector);
590        }
591        if let Some(ref val) = self.cdtr_agt
592            && config.validate_optional_fields
593        {
594            val.validate(&helpers::child_path(path, "CdtrAgt"), config, collector);
595        }
596        if let Some(ref val) = self.cdtr_agt_acct
597            && config.validate_optional_fields
598        {
599            val.validate(&helpers::child_path(path, "CdtrAgtAcct"), config, collector);
600        }
601        self.cdtr
602            .validate(&helpers::child_path(path, "Cdtr"), config, collector);
603        if let Some(ref val) = self.cdtr_acct
604            && config.validate_optional_fields
605        {
606            val.validate(&helpers::child_path(path, "CdtrAcct"), config, collector);
607        }
608        if let Some(ref vec) = self.instr_for_cdtr_agt
609            && config.validate_optional_fields
610        {
611            for item in vec {
612                item.validate(
613                    &helpers::child_path(path, "InstrForCdtrAgt"),
614                    config,
615                    collector,
616                );
617            }
618        }
619        if let Some(ref vec) = self.instr_for_nxt_agt
620            && config.validate_optional_fields
621        {
622            for item in vec {
623                item.validate(
624                    &helpers::child_path(path, "InstrForNxtAgt"),
625                    config,
626                    collector,
627                );
628            }
629        }
630        if let Some(ref val) = self.purp
631            && config.validate_optional_fields
632        {
633            val.validate(&helpers::child_path(path, "Purp"), config, collector);
634        }
635        if let Some(ref val) = self.rmt_inf
636            && config.validate_optional_fields
637        {
638            val.validate(&helpers::child_path(path, "RmtInf"), config, collector);
639        }
640    }
641}
642
643// FinancialInstitutionCreditTransferV08: Set of elements providing information specific to the individual credit transfer(s).
644#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
645pub struct FinancialInstitutionCreditTransferV08 {
646    #[serde(rename = "GrpHdr")]
647    pub grp_hdr: GroupHeader931,
648    #[serde(rename = "CdtTrfTxInf")]
649    pub cdt_trf_tx_inf: CreditTransferTransaction361,
650}
651
652impl Validate for FinancialInstitutionCreditTransferV08 {
653    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
654        self.grp_hdr
655            .validate(&helpers::child_path(path, "GrpHdr"), config, collector);
656        self.cdt_trf_tx_inf
657            .validate(&helpers::child_path(path, "CdtTrfTxInf"), config, collector);
658    }
659}
660
661// FinancialInstitutionIdentification181: Information that locates and identifies a specific address, as defined by postal services.
662#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
663pub struct FinancialInstitutionIdentification181 {
664    #[serde(rename = "BICFI", skip_serializing_if = "Option::is_none")]
665    pub bicfi: Option<String>,
666    #[serde(rename = "ClrSysMmbId", skip_serializing_if = "Option::is_none")]
667    pub clr_sys_mmb_id: Option<ClearingSystemMemberIdentification21>,
668    #[serde(rename = "LEI", skip_serializing_if = "Option::is_none")]
669    pub lei: Option<String>,
670    #[serde(rename = "Nm", skip_serializing_if = "Option::is_none")]
671    pub nm: Option<String>,
672    #[serde(rename = "PstlAdr", skip_serializing_if = "Option::is_none")]
673    pub pstl_adr: Option<PostalAddress241>,
674}
675
676impl Validate for FinancialInstitutionIdentification181 {
677    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
678        if let Some(ref val) = self.bicfi {
679            helpers::validate_pattern(
680                val,
681                "BICFI",
682                "[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}",
683                &helpers::child_path(path, "BICFI"),
684                config,
685                collector,
686            );
687        }
688        if let Some(ref val) = self.clr_sys_mmb_id
689            && config.validate_optional_fields
690        {
691            val.validate(&helpers::child_path(path, "ClrSysMmbId"), config, collector);
692        }
693        if let Some(ref val) = self.lei {
694            helpers::validate_pattern(
695                val,
696                "LEI",
697                "[A-Z0-9]{18,18}[0-9]{2,2}",
698                &helpers::child_path(path, "LEI"),
699                config,
700                collector,
701            );
702        }
703        if let Some(ref val) = self.nm {
704            helpers::validate_length(
705                val,
706                "Nm",
707                Some(1),
708                Some(140),
709                &helpers::child_path(path, "Nm"),
710                config,
711                collector,
712            );
713        }
714        if let Some(ref val) = self.nm {
715            helpers::validate_pattern(
716                val,
717                "Nm",
718                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
719                &helpers::child_path(path, "Nm"),
720                config,
721                collector,
722            );
723        }
724        if let Some(ref val) = self.pstl_adr
725            && config.validate_optional_fields
726        {
727            val.validate(&helpers::child_path(path, "PstlAdr"), config, collector);
728        }
729    }
730}
731
732// FinancialInstitutionIdentification182: Legal entity identifier of the financial institution.
733#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
734pub struct FinancialInstitutionIdentification182 {
735    #[serde(rename = "BICFI")]
736    pub bicfi: String,
737    #[serde(rename = "ClrSysMmbId", skip_serializing_if = "Option::is_none")]
738    pub clr_sys_mmb_id: Option<ClearingSystemMemberIdentification21>,
739    #[serde(rename = "LEI", skip_serializing_if = "Option::is_none")]
740    pub lei: Option<String>,
741}
742
743impl Validate for FinancialInstitutionIdentification182 {
744    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
745        helpers::validate_pattern(
746            &self.bicfi,
747            "BICFI",
748            "[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}",
749            &helpers::child_path(path, "BICFI"),
750            config,
751            collector,
752        );
753        if let Some(ref val) = self.clr_sys_mmb_id
754            && config.validate_optional_fields
755        {
756            val.validate(&helpers::child_path(path, "ClrSysMmbId"), config, collector);
757        }
758        if let Some(ref val) = self.lei {
759            helpers::validate_pattern(
760                val,
761                "LEI",
762                "[A-Z0-9]{18,18}[0-9]{2,2}",
763                &helpers::child_path(path, "LEI"),
764                config,
765                collector,
766            );
767        }
768    }
769}
770
771// GenericAccountIdentification11: Entity that assigns the identification.
772#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
773pub struct GenericAccountIdentification11 {
774    #[serde(rename = "Id")]
775    pub id: String,
776    #[serde(rename = "SchmeNm", skip_serializing_if = "Option::is_none")]
777    pub schme_nm: Option<AccountSchemeName1Choice1>,
778    #[serde(rename = "Issr", skip_serializing_if = "Option::is_none")]
779    pub issr: Option<String>,
780}
781
782impl Validate for GenericAccountIdentification11 {
783    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
784        helpers::validate_length(
785            &self.id,
786            "Id",
787            Some(1),
788            Some(34),
789            &helpers::child_path(path, "Id"),
790            config,
791            collector,
792        );
793        helpers::validate_pattern(
794            &self.id,
795            "Id",
796            "([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]([0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ]*(/[0-9a-zA-Z\\-\\?:\\(\\)\\.,'\\+ ])?)*)",
797            &helpers::child_path(path, "Id"),
798            config,
799            collector,
800        );
801        if let Some(ref val) = self.schme_nm
802            && config.validate_optional_fields
803        {
804            val.validate(&helpers::child_path(path, "SchmeNm"), config, collector);
805        }
806        if let Some(ref val) = self.issr {
807            helpers::validate_length(
808                val,
809                "Issr",
810                Some(1),
811                Some(35),
812                &helpers::child_path(path, "Issr"),
813                config,
814                collector,
815            );
816        }
817        if let Some(ref val) = self.issr {
818            helpers::validate_pattern(
819                val,
820                "Issr",
821                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
822                &helpers::child_path(path, "Issr"),
823                config,
824                collector,
825            );
826        }
827    }
828}
829
830// GroupHeader931: Specifies the details on how the settlement of the transaction(s) between the instructing agent and the instructed agent is completed.
831#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
832pub struct GroupHeader931 {
833    #[serde(rename = "MsgId")]
834    pub msg_id: String,
835    #[serde(rename = "CreDtTm")]
836    pub cre_dt_tm: String,
837    #[serde(rename = "NbOfTxs")]
838    pub nb_of_txs: Max15NumericTextfixed,
839    #[serde(rename = "SttlmInf")]
840    pub sttlm_inf: SettlementInstruction71,
841}
842
843impl Validate for GroupHeader931 {
844    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
845        helpers::validate_length(
846            &self.msg_id,
847            "MsgId",
848            Some(1),
849            Some(35),
850            &helpers::child_path(path, "MsgId"),
851            config,
852            collector,
853        );
854        helpers::validate_pattern(
855            &self.msg_id,
856            "MsgId",
857            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
858            &helpers::child_path(path, "MsgId"),
859            config,
860            collector,
861        );
862        helpers::validate_pattern(
863            &self.cre_dt_tm,
864            "CreDtTm",
865            ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
866            &helpers::child_path(path, "CreDtTm"),
867            config,
868            collector,
869        );
870        self.nb_of_txs
871            .validate(&helpers::child_path(path, "NbOfTxs"), config, collector);
872        self.sttlm_inf
873            .validate(&helpers::child_path(path, "SttlmInf"), config, collector);
874    }
875}
876
877// Instruction5Code: Please advise/contact (ultimate) creditor/claimant by the most efficient means of telecommunication.
878#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
879pub enum Instruction5Code {
880    #[default]
881    #[serde(rename = "PHOB")]
882    CodePHOB,
883    #[serde(rename = "TELB")]
884    CodeTELB,
885}
886
887impl Validate for Instruction5Code {
888    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
889        // Enum validation is typically empty
890    }
891}
892
893// InstructionForCreditorAgent21: Further information complementing the coded instruction or instruction to the creditor's agent that is bilaterally agreed or specific to a user community.
894#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
895pub struct InstructionForCreditorAgent21 {
896    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
897    pub cd: Option<Instruction5Code>,
898    #[serde(rename = "InstrInf", skip_serializing_if = "Option::is_none")]
899    pub instr_inf: Option<String>,
900}
901
902impl Validate for InstructionForCreditorAgent21 {
903    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
904        if let Some(ref val) = self.cd
905            && config.validate_optional_fields
906        {
907            val.validate(&helpers::child_path(path, "Cd"), config, collector);
908        }
909        if let Some(ref val) = self.instr_inf {
910            helpers::validate_length(
911                val,
912                "InstrInf",
913                Some(1),
914                Some(140),
915                &helpers::child_path(path, "InstrInf"),
916                config,
917                collector,
918            );
919        }
920        if let Some(ref val) = self.instr_inf {
921            helpers::validate_pattern(
922                val,
923                "InstrInf",
924                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
925                &helpers::child_path(path, "InstrInf"),
926                config,
927                collector,
928            );
929        }
930    }
931}
932
933// InstructionForNextAgent11: Further information complementing the coded instruction or instruction to the next agent that is bilaterally agreed or specific to a user community.
934#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
935pub struct InstructionForNextAgent11 {
936    #[serde(rename = "InstrInf", skip_serializing_if = "Option::is_none")]
937    pub instr_inf: Option<String>,
938}
939
940impl Validate for InstructionForNextAgent11 {
941    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
942        if let Some(ref val) = self.instr_inf {
943            helpers::validate_length(
944                val,
945                "InstrInf",
946                Some(1),
947                Some(35),
948                &helpers::child_path(path, "InstrInf"),
949                config,
950                collector,
951            );
952        }
953        if let Some(ref val) = self.instr_inf {
954            helpers::validate_pattern(
955                val,
956                "InstrInf",
957                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
958                &helpers::child_path(path, "InstrInf"),
959                config,
960                collector,
961            );
962        }
963    }
964}
965
966// LocalInstrument2Choice1: Specifies the local instrument, as a proprietary code.
967#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
968pub struct LocalInstrument2Choice1 {
969    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
970    pub cd: Option<String>,
971    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
972    pub prtry: Option<String>,
973}
974
975impl Validate for LocalInstrument2Choice1 {
976    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
977        if let Some(ref val) = self.cd {
978            helpers::validate_length(
979                val,
980                "Cd",
981                Some(1),
982                Some(35),
983                &helpers::child_path(path, "Cd"),
984                config,
985                collector,
986            );
987        }
988        if let Some(ref val) = self.prtry {
989            helpers::validate_length(
990                val,
991                "Prtry",
992                Some(1),
993                Some(35),
994                &helpers::child_path(path, "Prtry"),
995                config,
996                collector,
997            );
998        }
999        if let Some(ref val) = self.prtry {
1000            helpers::validate_pattern(
1001                val,
1002                "Prtry",
1003                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1004                &helpers::child_path(path, "Prtry"),
1005                config,
1006                collector,
1007            );
1008        }
1009    }
1010}
1011
1012// Max15NumericText_fixed: 1
1013#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1014pub enum Max15NumericTextfixed {
1015    #[default]
1016    #[serde(rename = "1")]
1017    Code1,
1018}
1019
1020impl Validate for Max15NumericTextfixed {
1021    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
1022        // Enum validation is typically empty
1023    }
1024}
1025
1026// PaymentIdentification71: Unique reference, as assigned by a clearing system, to unambiguously identify the instruction.
1027#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1028pub struct PaymentIdentification71 {
1029    #[serde(rename = "InstrId")]
1030    pub instr_id: String,
1031    #[serde(rename = "EndToEndId")]
1032    pub end_to_end_id: String,
1033    #[serde(rename = "TxId", skip_serializing_if = "Option::is_none")]
1034    pub tx_id: Option<String>,
1035    #[serde(rename = "UETR")]
1036    pub uetr: String,
1037    #[serde(rename = "ClrSysRef", skip_serializing_if = "Option::is_none")]
1038    pub clr_sys_ref: Option<String>,
1039}
1040
1041impl Validate for PaymentIdentification71 {
1042    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1043        helpers::validate_length(
1044            &self.instr_id,
1045            "InstrId",
1046            Some(1),
1047            Some(16),
1048            &helpers::child_path(path, "InstrId"),
1049            config,
1050            collector,
1051        );
1052        helpers::validate_pattern(
1053            &self.instr_id,
1054            "InstrId",
1055            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1056            &helpers::child_path(path, "InstrId"),
1057            config,
1058            collector,
1059        );
1060        helpers::validate_length(
1061            &self.end_to_end_id,
1062            "EndToEndId",
1063            Some(1),
1064            Some(35),
1065            &helpers::child_path(path, "EndToEndId"),
1066            config,
1067            collector,
1068        );
1069        helpers::validate_pattern(
1070            &self.end_to_end_id,
1071            "EndToEndId",
1072            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1073            &helpers::child_path(path, "EndToEndId"),
1074            config,
1075            collector,
1076        );
1077        if let Some(ref val) = self.tx_id {
1078            helpers::validate_length(
1079                val,
1080                "TxId",
1081                Some(1),
1082                Some(35),
1083                &helpers::child_path(path, "TxId"),
1084                config,
1085                collector,
1086            );
1087        }
1088        if let Some(ref val) = self.tx_id {
1089            helpers::validate_pattern(
1090                val,
1091                "TxId",
1092                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1093                &helpers::child_path(path, "TxId"),
1094                config,
1095                collector,
1096            );
1097        }
1098        helpers::validate_pattern(
1099            &self.uetr,
1100            "UETR",
1101            "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}",
1102            &helpers::child_path(path, "UETR"),
1103            config,
1104            collector,
1105        );
1106        if let Some(ref val) = self.clr_sys_ref {
1107            helpers::validate_length(
1108                val,
1109                "ClrSysRef",
1110                Some(1),
1111                Some(35),
1112                &helpers::child_path(path, "ClrSysRef"),
1113                config,
1114                collector,
1115            );
1116        }
1117        if let Some(ref val) = self.clr_sys_ref {
1118            helpers::validate_pattern(
1119                val,
1120                "ClrSysRef",
1121                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1122                &helpers::child_path(path, "ClrSysRef"),
1123                config,
1124                collector,
1125            );
1126        }
1127    }
1128}
1129
1130// PaymentTypeInformation281: Specifies the high level purpose of the instruction based on a set of pre-defined categories.
1131// 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.
1132#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1133pub struct PaymentTypeInformation281 {
1134    #[serde(rename = "InstrPrty", skip_serializing_if = "Option::is_none")]
1135    pub instr_prty: Option<Priority2Code>,
1136    #[serde(rename = "ClrChanl", skip_serializing_if = "Option::is_none")]
1137    pub clr_chanl: Option<ClearingChannel2Code>,
1138    #[serde(rename = "SvcLvl", skip_serializing_if = "Option::is_none")]
1139    pub svc_lvl: Option<Vec<ServiceLevel8Choice1>>,
1140    #[serde(rename = "LclInstrm", skip_serializing_if = "Option::is_none")]
1141    pub lcl_instrm: Option<LocalInstrument2Choice1>,
1142    #[serde(rename = "CtgyPurp", skip_serializing_if = "Option::is_none")]
1143    pub ctgy_purp: Option<CategoryPurpose1Choice1>,
1144}
1145
1146impl Validate for PaymentTypeInformation281 {
1147    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1148        if let Some(ref val) = self.instr_prty
1149            && config.validate_optional_fields
1150        {
1151            val.validate(&helpers::child_path(path, "InstrPrty"), config, collector);
1152        }
1153        if let Some(ref val) = self.clr_chanl
1154            && config.validate_optional_fields
1155        {
1156            val.validate(&helpers::child_path(path, "ClrChanl"), config, collector);
1157        }
1158        if let Some(ref vec) = self.svc_lvl
1159            && config.validate_optional_fields
1160        {
1161            for item in vec {
1162                item.validate(&helpers::child_path(path, "SvcLvl"), config, collector);
1163            }
1164        }
1165        if let Some(ref val) = self.lcl_instrm
1166            && config.validate_optional_fields
1167        {
1168            val.validate(&helpers::child_path(path, "LclInstrm"), config, collector);
1169        }
1170        if let Some(ref val) = self.ctgy_purp
1171            && config.validate_optional_fields
1172        {
1173            val.validate(&helpers::child_path(path, "CtgyPurp"), config, collector);
1174        }
1175    }
1176}
1177
1178// PostalAddress241: Information that locates and identifies a specific address, as defined by postal services, presented in free format text.
1179#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1180pub struct PostalAddress241 {
1181    #[serde(rename = "Dept", skip_serializing_if = "Option::is_none")]
1182    pub dept: Option<String>,
1183    #[serde(rename = "SubDept", skip_serializing_if = "Option::is_none")]
1184    pub sub_dept: Option<String>,
1185    #[serde(rename = "StrtNm", skip_serializing_if = "Option::is_none")]
1186    pub strt_nm: Option<String>,
1187    #[serde(rename = "BldgNb", skip_serializing_if = "Option::is_none")]
1188    pub bldg_nb: Option<String>,
1189    #[serde(rename = "BldgNm", skip_serializing_if = "Option::is_none")]
1190    pub bldg_nm: Option<String>,
1191    #[serde(rename = "Flr", skip_serializing_if = "Option::is_none")]
1192    pub flr: Option<String>,
1193    #[serde(rename = "PstBx", skip_serializing_if = "Option::is_none")]
1194    pub pst_bx: Option<String>,
1195    #[serde(rename = "Room", skip_serializing_if = "Option::is_none")]
1196    pub room: Option<String>,
1197    #[serde(rename = "PstCd", skip_serializing_if = "Option::is_none")]
1198    pub pst_cd: Option<String>,
1199    #[serde(rename = "TwnNm", skip_serializing_if = "Option::is_none")]
1200    pub twn_nm: Option<String>,
1201    #[serde(rename = "TwnLctnNm", skip_serializing_if = "Option::is_none")]
1202    pub twn_lctn_nm: Option<String>,
1203    #[serde(rename = "DstrctNm", skip_serializing_if = "Option::is_none")]
1204    pub dstrct_nm: Option<String>,
1205    #[serde(rename = "CtrySubDvsn", skip_serializing_if = "Option::is_none")]
1206    pub ctry_sub_dvsn: Option<String>,
1207    #[serde(rename = "Ctry", skip_serializing_if = "Option::is_none")]
1208    pub ctry: Option<String>,
1209    #[serde(rename = "AdrLine", skip_serializing_if = "Option::is_none")]
1210    pub adr_line: Option<Vec<String>>,
1211}
1212
1213impl Validate for PostalAddress241 {
1214    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1215        if let Some(ref val) = self.dept {
1216            helpers::validate_length(
1217                val,
1218                "Dept",
1219                Some(1),
1220                Some(70),
1221                &helpers::child_path(path, "Dept"),
1222                config,
1223                collector,
1224            );
1225        }
1226        if let Some(ref val) = self.dept {
1227            helpers::validate_pattern(
1228                val,
1229                "Dept",
1230                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1231                &helpers::child_path(path, "Dept"),
1232                config,
1233                collector,
1234            );
1235        }
1236        if let Some(ref val) = self.sub_dept {
1237            helpers::validate_length(
1238                val,
1239                "SubDept",
1240                Some(1),
1241                Some(70),
1242                &helpers::child_path(path, "SubDept"),
1243                config,
1244                collector,
1245            );
1246        }
1247        if let Some(ref val) = self.sub_dept {
1248            helpers::validate_pattern(
1249                val,
1250                "SubDept",
1251                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1252                &helpers::child_path(path, "SubDept"),
1253                config,
1254                collector,
1255            );
1256        }
1257        if let Some(ref val) = self.strt_nm {
1258            helpers::validate_length(
1259                val,
1260                "StrtNm",
1261                Some(1),
1262                Some(70),
1263                &helpers::child_path(path, "StrtNm"),
1264                config,
1265                collector,
1266            );
1267        }
1268        if let Some(ref val) = self.strt_nm {
1269            helpers::validate_pattern(
1270                val,
1271                "StrtNm",
1272                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1273                &helpers::child_path(path, "StrtNm"),
1274                config,
1275                collector,
1276            );
1277        }
1278        if let Some(ref val) = self.bldg_nb {
1279            helpers::validate_length(
1280                val,
1281                "BldgNb",
1282                Some(1),
1283                Some(16),
1284                &helpers::child_path(path, "BldgNb"),
1285                config,
1286                collector,
1287            );
1288        }
1289        if let Some(ref val) = self.bldg_nb {
1290            helpers::validate_pattern(
1291                val,
1292                "BldgNb",
1293                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1294                &helpers::child_path(path, "BldgNb"),
1295                config,
1296                collector,
1297            );
1298        }
1299        if let Some(ref val) = self.bldg_nm {
1300            helpers::validate_length(
1301                val,
1302                "BldgNm",
1303                Some(1),
1304                Some(35),
1305                &helpers::child_path(path, "BldgNm"),
1306                config,
1307                collector,
1308            );
1309        }
1310        if let Some(ref val) = self.bldg_nm {
1311            helpers::validate_pattern(
1312                val,
1313                "BldgNm",
1314                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1315                &helpers::child_path(path, "BldgNm"),
1316                config,
1317                collector,
1318            );
1319        }
1320        if let Some(ref val) = self.flr {
1321            helpers::validate_length(
1322                val,
1323                "Flr",
1324                Some(1),
1325                Some(70),
1326                &helpers::child_path(path, "Flr"),
1327                config,
1328                collector,
1329            );
1330        }
1331        if let Some(ref val) = self.flr {
1332            helpers::validate_pattern(
1333                val,
1334                "Flr",
1335                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1336                &helpers::child_path(path, "Flr"),
1337                config,
1338                collector,
1339            );
1340        }
1341        if let Some(ref val) = self.pst_bx {
1342            helpers::validate_length(
1343                val,
1344                "PstBx",
1345                Some(1),
1346                Some(16),
1347                &helpers::child_path(path, "PstBx"),
1348                config,
1349                collector,
1350            );
1351        }
1352        if let Some(ref val) = self.pst_bx {
1353            helpers::validate_pattern(
1354                val,
1355                "PstBx",
1356                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1357                &helpers::child_path(path, "PstBx"),
1358                config,
1359                collector,
1360            );
1361        }
1362        if let Some(ref val) = self.room {
1363            helpers::validate_length(
1364                val,
1365                "Room",
1366                Some(1),
1367                Some(70),
1368                &helpers::child_path(path, "Room"),
1369                config,
1370                collector,
1371            );
1372        }
1373        if let Some(ref val) = self.room {
1374            helpers::validate_pattern(
1375                val,
1376                "Room",
1377                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1378                &helpers::child_path(path, "Room"),
1379                config,
1380                collector,
1381            );
1382        }
1383        if let Some(ref val) = self.pst_cd {
1384            helpers::validate_length(
1385                val,
1386                "PstCd",
1387                Some(1),
1388                Some(16),
1389                &helpers::child_path(path, "PstCd"),
1390                config,
1391                collector,
1392            );
1393        }
1394        if let Some(ref val) = self.pst_cd {
1395            helpers::validate_pattern(
1396                val,
1397                "PstCd",
1398                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1399                &helpers::child_path(path, "PstCd"),
1400                config,
1401                collector,
1402            );
1403        }
1404        if let Some(ref val) = self.twn_nm {
1405            helpers::validate_length(
1406                val,
1407                "TwnNm",
1408                Some(1),
1409                Some(35),
1410                &helpers::child_path(path, "TwnNm"),
1411                config,
1412                collector,
1413            );
1414        }
1415        if let Some(ref val) = self.twn_nm {
1416            helpers::validate_pattern(
1417                val,
1418                "TwnNm",
1419                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1420                &helpers::child_path(path, "TwnNm"),
1421                config,
1422                collector,
1423            );
1424        }
1425        if let Some(ref val) = self.twn_lctn_nm {
1426            helpers::validate_length(
1427                val,
1428                "TwnLctnNm",
1429                Some(1),
1430                Some(35),
1431                &helpers::child_path(path, "TwnLctnNm"),
1432                config,
1433                collector,
1434            );
1435        }
1436        if let Some(ref val) = self.twn_lctn_nm {
1437            helpers::validate_pattern(
1438                val,
1439                "TwnLctnNm",
1440                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1441                &helpers::child_path(path, "TwnLctnNm"),
1442                config,
1443                collector,
1444            );
1445        }
1446        if let Some(ref val) = self.dstrct_nm {
1447            helpers::validate_length(
1448                val,
1449                "DstrctNm",
1450                Some(1),
1451                Some(35),
1452                &helpers::child_path(path, "DstrctNm"),
1453                config,
1454                collector,
1455            );
1456        }
1457        if let Some(ref val) = self.dstrct_nm {
1458            helpers::validate_pattern(
1459                val,
1460                "DstrctNm",
1461                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1462                &helpers::child_path(path, "DstrctNm"),
1463                config,
1464                collector,
1465            );
1466        }
1467        if let Some(ref val) = self.ctry_sub_dvsn {
1468            helpers::validate_length(
1469                val,
1470                "CtrySubDvsn",
1471                Some(1),
1472                Some(35),
1473                &helpers::child_path(path, "CtrySubDvsn"),
1474                config,
1475                collector,
1476            );
1477        }
1478        if let Some(ref val) = self.ctry_sub_dvsn {
1479            helpers::validate_pattern(
1480                val,
1481                "CtrySubDvsn",
1482                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1483                &helpers::child_path(path, "CtrySubDvsn"),
1484                config,
1485                collector,
1486            );
1487        }
1488        if let Some(ref val) = self.ctry {
1489            helpers::validate_pattern(
1490                val,
1491                "Ctry",
1492                "[A-Z]{2,2}",
1493                &helpers::child_path(path, "Ctry"),
1494                config,
1495                collector,
1496            );
1497        }
1498        if let Some(ref vec) = self.adr_line {
1499            for item in vec {
1500                helpers::validate_length(
1501                    item,
1502                    "AdrLine",
1503                    Some(1),
1504                    Some(70),
1505                    &helpers::child_path(path, "AdrLine"),
1506                    config,
1507                    collector,
1508                );
1509            }
1510        }
1511        if let Some(ref vec) = self.adr_line {
1512            for item in vec {
1513                helpers::validate_pattern(
1514                    item,
1515                    "AdrLine",
1516                    "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1517                    &helpers::child_path(path, "AdrLine"),
1518                    config,
1519                    collector,
1520                );
1521            }
1522        }
1523    }
1524}
1525
1526// Priority2Code: Priority level is normal.
1527#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1528pub enum Priority2Code {
1529    #[default]
1530    #[serde(rename = "HIGH")]
1531    CodeHIGH,
1532    #[serde(rename = "NORM")]
1533    CodeNORM,
1534}
1535
1536impl Validate for Priority2Code {
1537    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
1538        // Enum validation is typically empty
1539    }
1540}
1541
1542// Priority3Code: Priority level is normal.
1543#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1544pub enum Priority3Code {
1545    #[default]
1546    #[serde(rename = "URGT")]
1547    CodeURGT,
1548    #[serde(rename = "HIGH")]
1549    CodeHIGH,
1550    #[serde(rename = "NORM")]
1551    CodeNORM,
1552}
1553
1554impl Validate for Priority3Code {
1555    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
1556        // Enum validation is typically empty
1557    }
1558}
1559
1560// ProxyAccountIdentification11: Identification used to indicate the account identification under another specified name.
1561#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1562pub struct ProxyAccountIdentification11 {
1563    #[serde(rename = "Tp", skip_serializing_if = "Option::is_none")]
1564    pub tp: Option<ProxyAccountType1Choice1>,
1565    #[serde(rename = "Id")]
1566    pub id: String,
1567}
1568
1569impl Validate for ProxyAccountIdentification11 {
1570    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1571        if let Some(ref val) = self.tp
1572            && config.validate_optional_fields
1573        {
1574            val.validate(&helpers::child_path(path, "Tp"), config, collector);
1575        }
1576        helpers::validate_length(
1577            &self.id,
1578            "Id",
1579            Some(1),
1580            Some(320),
1581            &helpers::child_path(path, "Id"),
1582            config,
1583            collector,
1584        );
1585        helpers::validate_pattern(
1586            &self.id,
1587            "Id",
1588            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1589            &helpers::child_path(path, "Id"),
1590            config,
1591            collector,
1592        );
1593    }
1594}
1595
1596// ProxyAccountType1Choice1: Name of the identification scheme, in a free text form.
1597#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1598pub struct ProxyAccountType1Choice1 {
1599    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1600    pub cd: Option<String>,
1601    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1602    pub prtry: Option<String>,
1603}
1604
1605impl Validate for ProxyAccountType1Choice1 {
1606    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1607        if let Some(ref val) = self.cd {
1608            helpers::validate_length(
1609                val,
1610                "Cd",
1611                Some(1),
1612                Some(4),
1613                &helpers::child_path(path, "Cd"),
1614                config,
1615                collector,
1616            );
1617        }
1618        if let Some(ref val) = self.prtry {
1619            helpers::validate_length(
1620                val,
1621                "Prtry",
1622                Some(1),
1623                Some(35),
1624                &helpers::child_path(path, "Prtry"),
1625                config,
1626                collector,
1627            );
1628        }
1629        if let Some(ref val) = self.prtry {
1630            helpers::validate_pattern(
1631                val,
1632                "Prtry",
1633                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1634                &helpers::child_path(path, "Prtry"),
1635                config,
1636                collector,
1637            );
1638        }
1639    }
1640}
1641
1642// Purpose2Choice1: Purpose, in a proprietary form.
1643#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1644pub struct Purpose2Choice1 {
1645    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1646    pub cd: Option<String>,
1647    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1648    pub prtry: Option<String>,
1649}
1650
1651impl Validate for Purpose2Choice1 {
1652    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1653        if let Some(ref val) = self.cd {
1654            helpers::validate_length(
1655                val,
1656                "Cd",
1657                Some(1),
1658                Some(4),
1659                &helpers::child_path(path, "Cd"),
1660                config,
1661                collector,
1662            );
1663        }
1664        if let Some(ref val) = self.prtry {
1665            helpers::validate_length(
1666                val,
1667                "Prtry",
1668                Some(1),
1669                Some(35),
1670                &helpers::child_path(path, "Prtry"),
1671                config,
1672                collector,
1673            );
1674        }
1675        if let Some(ref val) = self.prtry {
1676            helpers::validate_pattern(
1677                val,
1678                "Prtry",
1679                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1680                &helpers::child_path(path, "Prtry"),
1681                config,
1682                collector,
1683            );
1684        }
1685    }
1686}
1687
1688// 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.
1689#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1690pub struct RemittanceInformation21 {
1691    #[serde(rename = "Ustrd", skip_serializing_if = "Option::is_none")]
1692    pub ustrd: Option<String>,
1693}
1694
1695impl Validate for RemittanceInformation21 {
1696    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1697        if let Some(ref val) = self.ustrd {
1698            helpers::validate_length(
1699                val,
1700                "Ustrd",
1701                Some(1),
1702                Some(140),
1703                &helpers::child_path(path, "Ustrd"),
1704                config,
1705                collector,
1706            );
1707        }
1708        if let Some(ref val) = self.ustrd {
1709            helpers::validate_pattern(
1710                val,
1711                "Ustrd",
1712                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]]+",
1713                &helpers::child_path(path, "Ustrd"),
1714                config,
1715                collector,
1716            );
1717        }
1718    }
1719}
1720
1721// ServiceLevel8Choice1: Specifies a pre-agreed service or level of service between the parties, as a proprietary code.
1722#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1723pub struct ServiceLevel8Choice1 {
1724    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
1725    pub cd: Option<String>,
1726    #[serde(rename = "Prtry", skip_serializing_if = "Option::is_none")]
1727    pub prtry: Option<String>,
1728}
1729
1730impl Validate for ServiceLevel8Choice1 {
1731    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1732        if let Some(ref val) = self.cd {
1733            helpers::validate_length(
1734                val,
1735                "Cd",
1736                Some(1),
1737                Some(4),
1738                &helpers::child_path(path, "Cd"),
1739                config,
1740                collector,
1741            );
1742        }
1743        if let Some(ref val) = self.prtry {
1744            helpers::validate_length(
1745                val,
1746                "Prtry",
1747                Some(1),
1748                Some(35),
1749                &helpers::child_path(path, "Prtry"),
1750                config,
1751                collector,
1752            );
1753        }
1754        if let Some(ref val) = self.prtry {
1755            helpers::validate_pattern(
1756                val,
1757                "Prtry",
1758                "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
1759                &helpers::child_path(path, "Prtry"),
1760                config,
1761                collector,
1762            );
1763        }
1764    }
1765}
1766
1767// SettlementDateTimeIndication11: Date and time at which a payment has been credited at the transaction administrator. In the case of TARGET, the date and time at which the payment has been credited at the receiving central bank, expressed in Central European Time (CET).
1768#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1769pub struct SettlementDateTimeIndication11 {
1770    #[serde(rename = "DbtDtTm", skip_serializing_if = "Option::is_none")]
1771    pub dbt_dt_tm: Option<String>,
1772    #[serde(rename = "CdtDtTm", skip_serializing_if = "Option::is_none")]
1773    pub cdt_dt_tm: Option<String>,
1774}
1775
1776impl Validate for SettlementDateTimeIndication11 {
1777    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1778        if let Some(ref val) = self.dbt_dt_tm {
1779            helpers::validate_pattern(
1780                val,
1781                "DbtDtTm",
1782                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1783                &helpers::child_path(path, "DbtDtTm"),
1784                config,
1785                collector,
1786            );
1787        }
1788        if let Some(ref val) = self.cdt_dt_tm {
1789            helpers::validate_pattern(
1790                val,
1791                "CdtDtTm",
1792                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1793                &helpers::child_path(path, "CdtDtTm"),
1794                config,
1795                collector,
1796            );
1797        }
1798    }
1799}
1800
1801// SettlementInstruction71: Unambiguous identification of the account of the instructed reimbursement agent account at its servicing agent in the payment chain.
1802#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1803pub struct SettlementInstruction71 {
1804    #[serde(rename = "SttlmMtd")]
1805    pub sttlm_mtd: SettlementMethod1Code1,
1806    #[serde(rename = "InstgRmbrsmntAgt", skip_serializing_if = "Option::is_none")]
1807    pub instg_rmbrsmnt_agt: Option<BranchAndFinancialInstitutionIdentification61>,
1808    #[serde(
1809        rename = "InstgRmbrsmntAgtAcct",
1810        skip_serializing_if = "Option::is_none"
1811    )]
1812    pub instg_rmbrsmnt_agt_acct: Option<CashAccount381>,
1813    #[serde(rename = "InstdRmbrsmntAgt", skip_serializing_if = "Option::is_none")]
1814    pub instd_rmbrsmnt_agt: Option<BranchAndFinancialInstitutionIdentification61>,
1815    #[serde(
1816        rename = "InstdRmbrsmntAgtAcct",
1817        skip_serializing_if = "Option::is_none"
1818    )]
1819    pub instd_rmbrsmnt_agt_acct: Option<CashAccount381>,
1820}
1821
1822impl Validate for SettlementInstruction71 {
1823    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1824        self.sttlm_mtd
1825            .validate(&helpers::child_path(path, "SttlmMtd"), config, collector);
1826        if let Some(ref val) = self.instg_rmbrsmnt_agt
1827            && config.validate_optional_fields
1828        {
1829            val.validate(
1830                &helpers::child_path(path, "InstgRmbrsmntAgt"),
1831                config,
1832                collector,
1833            );
1834        }
1835        if let Some(ref val) = self.instg_rmbrsmnt_agt_acct
1836            && config.validate_optional_fields
1837        {
1838            val.validate(
1839                &helpers::child_path(path, "InstgRmbrsmntAgtAcct"),
1840                config,
1841                collector,
1842            );
1843        }
1844        if let Some(ref val) = self.instd_rmbrsmnt_agt
1845            && config.validate_optional_fields
1846        {
1847            val.validate(
1848                &helpers::child_path(path, "InstdRmbrsmntAgt"),
1849                config,
1850                collector,
1851            );
1852        }
1853        if let Some(ref val) = self.instd_rmbrsmnt_agt_acct
1854            && config.validate_optional_fields
1855        {
1856            val.validate(
1857                &helpers::child_path(path, "InstdRmbrsmntAgtAcct"),
1858                config,
1859                collector,
1860            );
1861        }
1862    }
1863}
1864
1865// SettlementMethod1Code__1: Settlement is done through a cover payment.
1866#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1867pub enum SettlementMethod1Code1 {
1868    #[default]
1869    #[serde(rename = "COVE")]
1870    CodeCOVE,
1871}
1872
1873impl Validate for SettlementMethod1Code1 {
1874    fn validate(&self, _path: &str, _config: &ParserConfig, _collector: &mut ErrorCollector) {
1875        // Enum validation is typically empty
1876    }
1877}
1878
1879// SettlementTimeRequest21: Time by when the payment must be settled to avoid rejection.
1880#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
1881pub struct SettlementTimeRequest21 {
1882    #[serde(rename = "CLSTm", skip_serializing_if = "Option::is_none")]
1883    pub cls_tm: Option<String>,
1884    #[serde(rename = "TillTm", skip_serializing_if = "Option::is_none")]
1885    pub till_tm: Option<String>,
1886    #[serde(rename = "FrTm", skip_serializing_if = "Option::is_none")]
1887    pub fr_tm: Option<String>,
1888    #[serde(rename = "RjctTm", skip_serializing_if = "Option::is_none")]
1889    pub rjct_tm: Option<String>,
1890}
1891
1892impl Validate for SettlementTimeRequest21 {
1893    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
1894        if let Some(ref val) = self.cls_tm {
1895            helpers::validate_pattern(
1896                val,
1897                "CLSTm",
1898                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1899                &helpers::child_path(path, "CLSTm"),
1900                config,
1901                collector,
1902            );
1903        }
1904        if let Some(ref val) = self.till_tm {
1905            helpers::validate_pattern(
1906                val,
1907                "TillTm",
1908                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1909                &helpers::child_path(path, "TillTm"),
1910                config,
1911                collector,
1912            );
1913        }
1914        if let Some(ref val) = self.fr_tm {
1915            helpers::validate_pattern(
1916                val,
1917                "FrTm",
1918                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1919                &helpers::child_path(path, "FrTm"),
1920                config,
1921                collector,
1922            );
1923        }
1924        if let Some(ref val) = self.rjct_tm {
1925            helpers::validate_pattern(
1926                val,
1927                "RjctTm",
1928                ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
1929                &helpers::child_path(path, "RjctTm"),
1930                config,
1931                collector,
1932            );
1933        }
1934    }
1935}