mx_message/document/
camt_056_001_08.rs

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