mx_message/document/
camt_025_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
19use crate::parse_result::{ErrorCollector, ParserConfig};
20use crate::validation::{Validate, helpers};
21use serde::{Deserialize, Serialize};
22
23// MessageHeader91: Date and time at which the message was created.
24#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
25pub struct MessageHeader91 {
26    #[serde(rename = "MsgId")]
27    pub msg_id: String,
28    #[serde(rename = "CreDtTm")]
29    pub cre_dt_tm: String,
30}
31
32impl Validate for MessageHeader91 {
33    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
34        helpers::validate_length(
35            &self.msg_id,
36            "MsgId",
37            Some(1),
38            Some(35),
39            &helpers::child_path(path, "MsgId"),
40            config,
41            collector,
42        );
43        helpers::validate_pattern(
44            &self.msg_id,
45            "MsgId",
46            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
47            &helpers::child_path(path, "MsgId"),
48            config,
49            collector,
50        );
51        helpers::validate_pattern(
52            &self.cre_dt_tm,
53            "CreDtTm",
54            ".*(\\+|-)((0[0-9])|(1[0-4])):[0-5][0-9]",
55            &helpers::child_path(path, "CreDtTm"),
56            config,
57            collector,
58        );
59    }
60}
61
62// OriginalMessageAndIssuer11: Specifies the original message name identifier to which the message refers.
63#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
64pub struct OriginalMessageAndIssuer11 {
65    #[serde(rename = "MsgId")]
66    pub msg_id: String,
67    #[serde(rename = "MsgNmId")]
68    pub msg_nm_id: String,
69}
70
71impl Validate for OriginalMessageAndIssuer11 {
72    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
73        helpers::validate_length(
74            &self.msg_id,
75            "MsgId",
76            Some(1),
77            Some(35),
78            &helpers::child_path(path, "MsgId"),
79            config,
80            collector,
81        );
82        helpers::validate_pattern(
83            &self.msg_id,
84            "MsgId",
85            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
86            &helpers::child_path(path, "MsgId"),
87            config,
88            collector,
89        );
90        helpers::validate_length(
91            &self.msg_nm_id,
92            "MsgNmId",
93            Some(1),
94            Some(35),
95            &helpers::child_path(path, "MsgNmId"),
96            config,
97            collector,
98        );
99        helpers::validate_pattern(
100            &self.msg_nm_id,
101            "MsgNmId",
102            "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
103            &helpers::child_path(path, "MsgNmId"),
104            config,
105            collector,
106        );
107    }
108}
109
110// Receipt61: Gives the status of the request.
111#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
112pub struct Receipt61 {
113    #[serde(rename = "OrgnlMsgId")]
114    pub orgnl_msg_id: OriginalMessageAndIssuer11,
115    #[serde(rename = "ReqHdlg")]
116    pub req_hdlg: RequestHandling31,
117}
118
119impl Validate for Receipt61 {
120    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
121        self.orgnl_msg_id
122            .validate(&helpers::child_path(path, "OrgnlMsgId"), config, collector);
123        self.req_hdlg
124            .validate(&helpers::child_path(path, "ReqHdlg"), config, collector);
125    }
126}
127
128// ReceiptV08: Details of the receipt.
129#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
130pub struct ReceiptV08 {
131    #[serde(rename = "MsgHdr")]
132    pub msg_hdr: MessageHeader91,
133    #[serde(rename = "RctDtls")]
134    pub rct_dtls: Vec<Receipt61>,
135}
136
137impl Validate for ReceiptV08 {
138    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
139        self.msg_hdr
140            .validate(&helpers::child_path(path, "MsgHdr"), config, collector);
141        for item in &self.rct_dtls {
142            item.validate(&helpers::child_path(path, "RctDtls"), config, collector);
143        }
144    }
145}
146
147// RequestHandling31: Provides detailed information on the status reason.
148#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
149pub struct RequestHandling31 {
150    #[serde(rename = "Sts")]
151    pub sts: RequestStatus1Choice1,
152    #[serde(rename = "StsRsn", skip_serializing_if = "Option::is_none")]
153    pub sts_rsn: Option<StatusReasonInformation141>,
154}
155
156impl Validate for RequestHandling31 {
157    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
158        self.sts
159            .validate(&helpers::child_path(path, "Sts"), config, collector);
160        if let Some(ref val) = self.sts_rsn
161            && config.validate_optional_fields
162        {
163            val.validate(&helpers::child_path(path, "StsRsn"), config, collector);
164        }
165    }
166}
167
168// RequestStatus1Choice1: Request status, as published in an external request status code set.
169#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
170pub struct RequestStatus1Choice1 {
171    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
172    pub cd: Option<String>,
173}
174
175impl Validate for RequestStatus1Choice1 {
176    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
177        if let Some(ref val) = self.cd {
178            helpers::validate_length(
179                val,
180                "Cd",
181                Some(1),
182                Some(4),
183                &helpers::child_path(path, "Cd"),
184                config,
185                collector,
186            );
187        }
188    }
189}
190
191// StatusReason6Choice1: Reason for the status, as published in an external reason code list.
192#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
193pub struct StatusReason6Choice1 {
194    #[serde(rename = "Cd", skip_serializing_if = "Option::is_none")]
195    pub cd: Option<String>,
196}
197
198impl Validate for StatusReason6Choice1 {
199    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
200        if let Some(ref val) = self.cd {
201            helpers::validate_length(
202                val,
203                "Cd",
204                Some(1),
205                Some(4),
206                &helpers::child_path(path, "Cd"),
207                config,
208                collector,
209            );
210        }
211    }
212}
213
214// StatusReasonInformation141: Further details on the status reason.
215//
216// Usage: Additional information can be used for several purposes such as the reporting of repaired information.
217#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
218pub struct StatusReasonInformation141 {
219    #[serde(rename = "Rsn", skip_serializing_if = "Option::is_none")]
220    pub rsn: Option<StatusReason6Choice1>,
221    #[serde(rename = "AddtlInf", skip_serializing_if = "Option::is_none")]
222    pub addtl_inf: Option<Vec<String>>,
223}
224
225impl Validate for StatusReasonInformation141 {
226    fn validate(&self, path: &str, config: &ParserConfig, collector: &mut ErrorCollector) {
227        if let Some(ref val) = self.rsn
228            && config.validate_optional_fields
229        {
230            val.validate(&helpers::child_path(path, "Rsn"), config, collector);
231        }
232        if let Some(ref vec) = self.addtl_inf {
233            for item in vec {
234                helpers::validate_length(
235                    item,
236                    "AddtlInf",
237                    Some(1),
238                    Some(105),
239                    &helpers::child_path(path, "AddtlInf"),
240                    config,
241                    collector,
242                );
243            }
244        }
245        if let Some(ref vec) = self.addtl_inf {
246            for item in vec {
247                helpers::validate_pattern(
248                    item,
249                    "AddtlInf",
250                    "[0-9a-zA-Z/\\-\\?:\\(\\)\\.,'\\+ ]+",
251                    &helpers::child_path(path, "AddtlInf"),
252                    config,
253                    collector,
254                );
255            }
256        }
257    }
258}