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