1use super::swift_utils::{parse_bic, parse_swift_chars};
24use crate::errors::ParseError;
25use crate::traits::SwiftField;
26use serde::{Deserialize, Serialize};
27
28#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct Field50NoOption {
33 pub name_and_address: Vec<String>,
35}
36
37impl SwiftField for Field50NoOption {
38 fn parse(input: &str) -> crate::Result<Self>
39 where
40 Self: Sized,
41 {
42 let lines: Vec<String> = input.lines().map(|line| line.to_string()).collect();
43
44 if lines.is_empty() {
45 return Err(ParseError::InvalidFormat {
46 message: "Field 50 (No Option) must have at least one line".to_string(),
47 });
48 }
49
50 if lines.len() > 4 {
51 return Err(ParseError::InvalidFormat {
52 message: format!(
53 "Field 50 (No Option) cannot have more than 4 lines, found {}",
54 lines.len()
55 ),
56 });
57 }
58
59 for (i, line) in lines.iter().enumerate() {
61 if line.len() > 35 {
62 return Err(ParseError::InvalidFormat {
63 message: format!("Field 50 (No Option) line {} exceeds 35 characters", i + 1),
64 });
65 }
66 parse_swift_chars(line, &format!("Field 50 (No Option) line {}", i + 1))?;
67 }
68
69 Ok(Field50NoOption {
70 name_and_address: lines,
71 })
72 }
73
74 fn to_swift_string(&self) -> String {
75 format!(":50:{}", self.name_and_address.join("\n"))
76 }
77}
78
79#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
84pub struct Field50A {
85 pub party_identifier: Option<String>,
87 pub name_and_address: Vec<String>,
89}
90
91impl SwiftField for Field50A {
92 fn parse(input: &str) -> crate::Result<Self>
93 where
94 Self: Sized,
95 {
96 let lines: Vec<&str> = input.lines().collect();
97
98 if lines.is_empty() {
99 return Err(ParseError::InvalidFormat {
100 message: "Field 50A must have at least one line".to_string(),
101 });
102 }
103
104 let mut party_identifier = None;
105 let mut name_and_address = Vec::new();
106 let mut start_index = 0;
107
108 if lines[0].starts_with('/') {
110 let identifier = &lines[0][1..];
111 if identifier.len() > 34 {
112 return Err(ParseError::InvalidFormat {
113 message: "Field 50A party identifier exceeds 34 characters".to_string(),
114 });
115 }
116 parse_swift_chars(identifier, "Field 50A party identifier")?;
117 party_identifier = Some(identifier.to_string());
118 start_index = 1;
119 }
120
121 for (i, line) in lines.iter().enumerate().skip(start_index) {
123 if line.len() < 2 || !line.chars().next().is_some_and(|c| c.is_ascii_digit()) {
125 return Err(ParseError::InvalidFormat {
126 message: format!(
127 "Field 50A line {} must start with line number",
128 i - start_index + 1
129 ),
130 });
131 }
132
133 if line.chars().nth(1) != Some('/') {
134 return Err(ParseError::InvalidFormat {
135 message: format!(
136 "Field 50A line {} must have '/' after line number",
137 i - start_index + 1
138 ),
139 });
140 }
141
142 let text = &line[2..];
143 if text.len() > 33 {
144 return Err(ParseError::InvalidFormat {
145 message: format!(
146 "Field 50A line {} text exceeds 33 characters",
147 i - start_index + 1
148 ),
149 });
150 }
151
152 parse_swift_chars(text, &format!("Field 50A line {}", i - start_index + 1))?;
153 name_and_address.push(text.to_string());
154 }
155
156 if name_and_address.is_empty() {
157 return Err(ParseError::InvalidFormat {
158 message: "Field 50A must have at least one name/address line".to_string(),
159 });
160 }
161
162 if name_and_address.len() > 4 {
163 return Err(ParseError::InvalidFormat {
164 message: format!(
165 "Field 50A cannot have more than 4 name/address lines, found {}",
166 name_and_address.len()
167 ),
168 });
169 }
170
171 Ok(Field50A {
172 party_identifier,
173 name_and_address,
174 })
175 }
176
177 fn to_swift_string(&self) -> String {
178 let mut result = Vec::new();
179
180 if let Some(ref id) = self.party_identifier {
181 result.push(format!("/{}", id));
182 }
183
184 for (i, line) in self.name_and_address.iter().enumerate() {
185 result.push(format!("{}/{}", i + 1, line));
186 }
187
188 format!(":50A:{}", result.join("\n"))
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
197pub struct Field50F {
198 pub account: String,
200 #[serde(skip_serializing_if = "Option::is_none")]
202 pub party_identifier: Option<String>,
203 #[serde(skip_serializing_if = "Option::is_none")]
205 pub name_and_address: Option<Vec<String>>,
206 pub bic: String,
208}
209
210impl SwiftField for Field50F {
211 fn parse(input: &str) -> crate::Result<Self>
212 where
213 Self: Sized,
214 {
215 let lines: Vec<&str> = input.lines().collect();
216
217 if lines.len() < 2 {
218 return Err(ParseError::InvalidFormat {
219 message: format!(
220 "Field 50F must have at least 2 lines (account + BIC), found {}",
221 lines.len()
222 ),
223 });
224 }
225
226 let account = lines[0];
228 if account.is_empty() || account.len() > 35 {
229 return Err(ParseError::InvalidFormat {
230 message: "Field 50F account must be 1-35 characters".to_string(),
231 });
232 }
233 parse_swift_chars(account, "Field 50F account")?;
234
235 let bic = parse_bic(lines[lines.len() - 1])?;
237
238 let mut party_identifier = None;
240 let mut name_start = 1;
241
242 if lines.len() > 2 && lines[1].starts_with('/') {
243 let party_id = &lines[1][1..]; if party_id.len() > 34 {
245 return Err(ParseError::InvalidFormat {
246 message: "Field 50F party identifier exceeds 34 characters".to_string(),
247 });
248 }
249 parse_swift_chars(party_id, "Field 50F party identifier")?;
250 party_identifier = Some(party_id.to_string());
251 name_start = 2;
252 }
253
254 let mut name_and_address = Vec::new();
256 for line in &lines[name_start..lines.len() - 1] {
257 if line.len() > 35 {
258 return Err(ParseError::InvalidFormat {
259 message: "Field 50F name/address line exceeds 35 characters".to_string(),
260 });
261 }
262 parse_swift_chars(line, "Field 50F name/address")?;
263 name_and_address.push(line.to_string());
264 }
265
266 Ok(Field50F {
267 account: account.to_string(),
268 party_identifier,
269 name_and_address: if name_and_address.is_empty() {
270 None
271 } else {
272 Some(name_and_address)
273 },
274 bic,
275 })
276 }
277
278 fn to_swift_string(&self) -> String {
279 let mut lines = vec![self.account.clone()];
280
281 if let Some(ref party_id) = self.party_identifier {
282 lines.push(format!("/{}", party_id));
283 }
284
285 if let Some(ref addr) = self.name_and_address {
286 lines.extend(addr.clone());
287 }
288
289 lines.push(self.bic.clone());
290
291 format!(":50F:{}", lines.join("\n"))
292 }
293}
294
295#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
300pub struct Field50K {
301 pub account: Option<String>,
303 pub name_and_address: Vec<String>,
305}
306
307impl SwiftField for Field50K {
308 fn parse(input: &str) -> crate::Result<Self>
309 where
310 Self: Sized,
311 {
312 let lines: Vec<&str> = input.lines().collect();
313
314 if lines.is_empty() {
315 return Err(ParseError::InvalidFormat {
316 message: "Field 50K must have at least one line".to_string(),
317 });
318 }
319
320 let mut account = None;
321 let mut name_and_address = Vec::new();
322 let mut start_index = 0;
323
324 if lines[0].starts_with('/') {
326 let acc = &lines[0][1..];
327 if acc.len() > 34 {
328 return Err(ParseError::InvalidFormat {
329 message: "Field 50K account exceeds 34 characters".to_string(),
330 });
331 }
332 parse_swift_chars(acc, "Field 50K account")?;
333 account = Some(acc.to_string());
335 start_index = 1;
336 }
337
338 for (i, line) in lines.iter().enumerate().skip(start_index) {
340 if line.len() > 35 {
341 return Err(ParseError::InvalidFormat {
342 message: format!(
343 "Field 50K line {} exceeds 35 characters",
344 i - start_index + 1
345 ),
346 });
347 }
348 parse_swift_chars(line, &format!("Field 50K line {}", i - start_index + 1))?;
349 name_and_address.push(line.to_string());
350 }
351
352 if name_and_address.is_empty() {
353 return Err(ParseError::InvalidFormat {
354 message: "Field 50K must have at least one name/address line".to_string(),
355 });
356 }
357
358 if name_and_address.len() > 4 {
359 return Err(ParseError::InvalidFormat {
360 message: format!(
361 "Field 50K cannot have more than 4 name/address lines, found {}",
362 name_and_address.len()
363 ),
364 });
365 }
366
367 Ok(Field50K {
368 account,
369 name_and_address,
370 })
371 }
372
373 fn to_swift_string(&self) -> String {
374 let mut result = Vec::new();
375
376 if let Some(ref acc) = self.account {
378 result.push(format!("/{}", acc));
379 }
380
381 for line in &self.name_and_address {
382 result.push(line.clone());
383 }
384
385 format!(":50K:{}", result.join("\n"))
386 }
387}
388
389#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
393pub struct Field50C {
394 pub bic: String,
396}
397
398impl SwiftField for Field50C {
399 fn parse(input: &str) -> crate::Result<Self>
400 where
401 Self: Sized,
402 {
403 let bic = parse_bic(input)?;
404 Ok(Field50C { bic })
405 }
406
407 fn to_swift_string(&self) -> String {
408 format!(":50C:{}", self.bic)
409 }
410}
411
412#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
416pub struct Field50L {
417 pub party_identifier: String,
419}
420
421impl SwiftField for Field50L {
422 fn parse(input: &str) -> crate::Result<Self>
423 where
424 Self: Sized,
425 {
426 if input.contains('\n') {
429 return Err(ParseError::InvalidFormat {
430 message: "Field 50L party identifier must be single line".to_string(),
431 });
432 }
433
434 if input.is_empty() || input.len() > 35 {
435 return Err(ParseError::InvalidFormat {
436 message: "Field 50L party identifier must be 1-35 characters".to_string(),
437 });
438 }
439
440 parse_swift_chars(input, "Field 50L party identifier")?;
441
442 Ok(Field50L {
443 party_identifier: input.to_string(),
444 })
445 }
446
447 fn to_swift_string(&self) -> String {
448 format!(":50L:{}", self.party_identifier)
449 }
450}
451
452#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
456pub struct Field50G {
457 pub account: String,
459 pub bic: String,
461}
462
463impl SwiftField for Field50G {
464 fn parse(input: &str) -> crate::Result<Self>
465 where
466 Self: Sized,
467 {
468 let lines: Vec<&str> = input.lines().collect();
469
470 if lines.len() != 2 {
471 return Err(ParseError::InvalidFormat {
472 message: format!("Field 50G must have exactly 2 lines, found {}", lines.len()),
473 });
474 }
475
476 if !lines[0].starts_with('/') {
478 return Err(ParseError::InvalidFormat {
479 message: "Field 50G account must start with '/'".to_string(),
480 });
481 }
482
483 let account = &lines[0][1..];
484 if account.is_empty() || account.len() > 34 {
485 return Err(ParseError::InvalidFormat {
486 message: "Field 50G account must be 1-34 characters".to_string(),
487 });
488 }
489 parse_swift_chars(account, "Field 50G account")?;
490
491 let bic = parse_bic(lines[1])?;
493
494 Ok(Field50G {
495 account: account.to_string(),
496 bic,
497 })
498 }
499
500 fn to_swift_string(&self) -> String {
501 format!(":50G:/{}\n{}", self.account, self.bic)
502 }
503}
504
505#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
509pub struct Field50H {
510 pub account: String,
512 pub name_and_address: Vec<String>,
514}
515
516impl SwiftField for Field50H {
517 fn parse(input: &str) -> crate::Result<Self>
518 where
519 Self: Sized,
520 {
521 let lines: Vec<&str> = input.lines().collect();
522
523 if lines.len() < 2 {
524 return Err(ParseError::InvalidFormat {
525 message: "Field 50H must have at least 2 lines".to_string(),
526 });
527 }
528
529 if !lines[0].starts_with('/') {
531 return Err(ParseError::InvalidFormat {
532 message: "Field 50H account must start with '/'".to_string(),
533 });
534 }
535
536 let account = &lines[0][1..];
537 if account.is_empty() || account.len() > 34 {
538 return Err(ParseError::InvalidFormat {
539 message: "Field 50H account must be 1-34 characters".to_string(),
540 });
541 }
542 parse_swift_chars(account, "Field 50H account")?;
543
544 let mut name_and_address = Vec::new();
546 for (i, line) in lines.iter().enumerate().skip(1) {
547 if line.len() > 35 {
548 return Err(ParseError::InvalidFormat {
549 message: format!("Field 50H line {} exceeds 35 characters", i),
550 });
551 }
552 parse_swift_chars(line, &format!("Field 50H line {}", i))?;
553 name_and_address.push(line.to_string());
554 }
555
556 if name_and_address.len() > 4 {
557 return Err(ParseError::InvalidFormat {
558 message: format!(
559 "Field 50H cannot have more than 4 name/address lines, found {}",
560 name_and_address.len()
561 ),
562 });
563 }
564
565 Ok(Field50H {
566 account: account.to_string(),
567 name_and_address,
568 })
569 }
570
571 fn to_swift_string(&self) -> String {
572 let mut result = vec![format!("/{}", self.account)];
573 result.extend(self.name_and_address.clone());
574 format!(":50H:{}", result.join("\n"))
575 }
576}
577
578#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
580pub enum Field50InstructingParty {
581 #[serde(rename = "50C")]
582 C(Field50C),
583 #[serde(rename = "50L")]
584 L(Field50L),
585}
586
587impl SwiftField for Field50InstructingParty {
588 fn parse(input: &str) -> crate::Result<Self>
589 where
590 Self: Sized,
591 {
592 let trimmed = input.trim();
597
598 if let Ok(field) = Field50C::parse(trimmed) {
600 return Ok(Field50InstructingParty::C(field));
601 }
602
603 if let Ok(field) = Field50L::parse(trimmed) {
605 return Ok(Field50InstructingParty::L(field));
606 }
607
608 Err(ParseError::InvalidFormat {
609 message: "Field 50 Instructing Party could not be parsed as option C or L".to_string(),
610 })
611 }
612
613 fn parse_with_variant(
614 value: &str,
615 variant: Option<&str>,
616 _field_tag: Option<&str>,
617 ) -> crate::Result<Self>
618 where
619 Self: Sized,
620 {
621 match variant {
622 Some("C") => {
623 let field = Field50C::parse(value)?;
624 Ok(Field50InstructingParty::C(field))
625 }
626 Some("L") => {
627 let field = Field50L::parse(value)?;
628 Ok(Field50InstructingParty::L(field))
629 }
630 _ => {
631 Self::parse(value)
633 }
634 }
635 }
636
637 fn to_swift_string(&self) -> String {
638 match self {
639 Field50InstructingParty::C(field) => field.to_swift_string(),
640 Field50InstructingParty::L(field) => field.to_swift_string(),
641 }
642 }
643}
644
645#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
647pub enum Field50OrderingCustomerFGH {
648 #[serde(rename = "50F")]
649 F(Field50F),
650 #[serde(rename = "50G")]
651 G(Field50G),
652 #[serde(rename = "50H")]
653 H(Field50H),
654}
655
656impl SwiftField for Field50OrderingCustomerFGH {
657 fn parse(input: &str) -> crate::Result<Self>
658 where
659 Self: Sized,
660 {
661 let lines: Vec<&str> = input.lines().collect();
662
663 if lines.len() >= 2 {
664 if (8..=11).contains(&lines[1].len()) {
666 if lines[0].starts_with('/') {
668 if let Ok(field) = Field50G::parse(input) {
670 return Ok(Field50OrderingCustomerFGH::G(field));
671 }
672 } else {
673 if let Ok(field) = Field50F::parse(input) {
675 return Ok(Field50OrderingCustomerFGH::F(field));
676 }
677 }
678 }
679
680 if lines[0].starts_with('/')
682 && let Ok(field) = Field50H::parse(input)
683 {
684 return Ok(Field50OrderingCustomerFGH::H(field));
685 }
686 }
687
688 Err(ParseError::InvalidFormat {
689 message: "Field 50 Ordering Customer could not be parsed as option F, G or H"
690 .to_string(),
691 })
692 }
693
694 fn parse_with_variant(
695 value: &str,
696 variant: Option<&str>,
697 _field_tag: Option<&str>,
698 ) -> crate::Result<Self>
699 where
700 Self: Sized,
701 {
702 match variant {
703 Some("F") => {
704 let field = Field50F::parse(value)?;
705 Ok(Field50OrderingCustomerFGH::F(field))
706 }
707 Some("G") => {
708 let field = Field50G::parse(value)?;
709 Ok(Field50OrderingCustomerFGH::G(field))
710 }
711 Some("H") => {
712 let field = Field50H::parse(value)?;
713 Ok(Field50OrderingCustomerFGH::H(field))
714 }
715 _ => {
716 Self::parse(value)
718 }
719 }
720 }
721
722 fn to_swift_string(&self) -> String {
723 match self {
724 Field50OrderingCustomerFGH::F(field) => field.to_swift_string(),
725 Field50OrderingCustomerFGH::G(field) => field.to_swift_string(),
726 Field50OrderingCustomerFGH::H(field) => field.to_swift_string(),
727 }
728 }
729}
730
731#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
733pub enum Field50OrderingCustomerAFK {
734 #[serde(rename = "50A")]
735 A(Field50A),
736 #[serde(rename = "50F")]
737 F(Field50F),
738 #[serde(rename = "50K")]
739 K(Field50K),
740}
741
742impl SwiftField for Field50OrderingCustomerAFK {
743 fn parse(input: &str) -> crate::Result<Self>
744 where
745 Self: Sized,
746 {
747 let lines: Vec<&str> = input.lines().collect();
749
750 let mut has_numbered_lines = false;
752 for line in &lines {
753 let mut chars = line.chars();
754 if line.len() >= 2
755 && chars.next().is_some_and(|c| c.is_ascii_digit())
756 && chars.next() == Some('/')
757 {
758 has_numbered_lines = true;
759 break;
760 }
761 }
762
763 if has_numbered_lines && let Ok(field) = Field50A::parse(input) {
764 return Ok(Field50OrderingCustomerAFK::A(field));
765 }
766
767 if lines.len() == 2
769 && (8..=11).contains(&lines[1].len())
770 && let Ok(field) = Field50F::parse(input)
771 {
772 return Ok(Field50OrderingCustomerAFK::F(field));
773 }
774
775 if let Ok(field) = Field50K::parse(input) {
777 return Ok(Field50OrderingCustomerAFK::K(field));
778 }
779
780 Err(ParseError::InvalidFormat {
781 message: "Field 50 Ordering Customer could not be parsed as option A, F or K"
782 .to_string(),
783 })
784 }
785
786 fn parse_with_variant(
787 value: &str,
788 variant: Option<&str>,
789 _field_tag: Option<&str>,
790 ) -> crate::Result<Self>
791 where
792 Self: Sized,
793 {
794 match variant {
795 Some("A") => {
796 let field = Field50A::parse(value)?;
797 Ok(Field50OrderingCustomerAFK::A(field))
798 }
799 Some("F") => {
800 let field = Field50F::parse(value)?;
801 Ok(Field50OrderingCustomerAFK::F(field))
802 }
803 Some("K") => {
804 let field = Field50K::parse(value)?;
805 Ok(Field50OrderingCustomerAFK::K(field))
806 }
807 _ => {
808 Self::parse(value)
810 }
811 }
812 }
813
814 fn to_swift_string(&self) -> String {
815 match self {
816 Field50OrderingCustomerAFK::A(field) => field.to_swift_string(),
817 Field50OrderingCustomerAFK::F(field) => field.to_swift_string(),
818 Field50OrderingCustomerAFK::K(field) => field.to_swift_string(),
819 }
820 }
821
822 fn get_variant_tag(&self) -> Option<&'static str> {
823 match self {
824 Field50OrderingCustomerAFK::A(_) => Some("A"),
825 Field50OrderingCustomerAFK::F(_) => Some("F"),
826 Field50OrderingCustomerAFK::K(_) => Some("K"),
827 }
828 }
829}
830
831#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
833pub enum Field50OrderingCustomerNCF {
834 #[serde(rename = "50")]
835 NoOption(Field50NoOption),
836 #[serde(rename = "50C")]
837 C(Field50C),
838 #[serde(rename = "50F")]
839 F(Field50F),
840}
841
842impl SwiftField for Field50OrderingCustomerNCF {
843 fn parse(input: &str) -> crate::Result<Self>
844 where
845 Self: Sized,
846 {
847 let lines: Vec<&str> = input.lines().collect();
848
849 if lines.len() == 1
851 && (8..=11).contains(&lines[0].len())
852 && let Ok(field) = Field50C::parse(input)
853 {
854 return Ok(Field50OrderingCustomerNCF::C(field));
855 }
856
857 if lines.len() == 2
859 && (8..=11).contains(&lines[1].len())
860 && let Ok(field) = Field50F::parse(input)
861 {
862 return Ok(Field50OrderingCustomerNCF::F(field));
863 }
864
865 if let Ok(field) = Field50NoOption::parse(input) {
867 return Ok(Field50OrderingCustomerNCF::NoOption(field));
868 }
869
870 Err(ParseError::InvalidFormat {
871 message: "Field 50 Ordering Customer could not be parsed as No Option, C or F"
872 .to_string(),
873 })
874 }
875
876 fn parse_with_variant(
877 value: &str,
878 variant: Option<&str>,
879 _field_tag: Option<&str>,
880 ) -> crate::Result<Self>
881 where
882 Self: Sized,
883 {
884 match variant {
885 None => {
886 let field = Field50NoOption::parse(value)?;
887 Ok(Field50OrderingCustomerNCF::NoOption(field))
888 }
889 Some("C") => {
890 let field = Field50C::parse(value)?;
891 Ok(Field50OrderingCustomerNCF::C(field))
892 }
893 Some("F") => {
894 let field = Field50F::parse(value)?;
895 Ok(Field50OrderingCustomerNCF::F(field))
896 }
897 _ => {
898 Self::parse(value)
900 }
901 }
902 }
903
904 fn to_swift_string(&self) -> String {
905 match self {
906 Field50OrderingCustomerNCF::NoOption(field) => field.to_swift_string(),
907 Field50OrderingCustomerNCF::C(field) => field.to_swift_string(),
908 Field50OrderingCustomerNCF::F(field) => field.to_swift_string(),
909 }
910 }
911}
912
913#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
915pub enum Field50Creditor {
916 #[serde(rename = "50A")]
917 A(Field50A),
918 #[serde(rename = "50K")]
919 K(Field50K),
920}
921
922impl SwiftField for Field50Creditor {
923 fn parse(input: &str) -> crate::Result<Self>
924 where
925 Self: Sized,
926 {
927 let lines: Vec<&str> = input.lines().collect();
929
930 for line in &lines {
931 let mut chars = line.chars();
932 if line.len() >= 2
933 && chars.next().is_some_and(|c| c.is_ascii_digit())
934 && chars.next() == Some('/')
935 {
936 if let Ok(field) = Field50A::parse(input) {
938 return Ok(Field50Creditor::A(field));
939 }
940 }
941 }
942
943 if let Ok(field) = Field50K::parse(input) {
945 return Ok(Field50Creditor::K(field));
946 }
947
948 Err(ParseError::InvalidFormat {
949 message: "Field 50 Creditor could not be parsed as option A or K".to_string(),
950 })
951 }
952
953 fn parse_with_variant(
954 value: &str,
955 variant: Option<&str>,
956 _field_tag: Option<&str>,
957 ) -> crate::Result<Self>
958 where
959 Self: Sized,
960 {
961 match variant {
962 Some("A") => {
963 let field = Field50A::parse(value)?;
964 Ok(Field50Creditor::A(field))
965 }
966 Some("K") => {
967 let field = Field50K::parse(value)?;
968 Ok(Field50Creditor::K(field))
969 }
970 _ => {
971 Self::parse(value)
973 }
974 }
975 }
976
977 fn to_swift_string(&self) -> String {
978 match self {
979 Field50Creditor::A(field) => field.to_swift_string(),
980 Field50Creditor::K(field) => field.to_swift_string(),
981 }
982 }
983
984 fn get_variant_tag(&self) -> Option<&'static str> {
985 match self {
986 Field50Creditor::A(_) => Some("A"),
987 Field50Creditor::K(_) => Some("K"),
988 }
989 }
990}
991
992pub type Field50 = Field50OrderingCustomerNCF;
994
995#[cfg(test)]
996mod tests {
997 use super::*;
998
999 #[test]
1000 fn test_field50_no_option() {
1001 let field = Field50NoOption::parse("JOHN DOE\n123 MAIN ST\nNEW YORK").unwrap();
1002 assert_eq!(field.name_and_address.len(), 3);
1003 assert_eq!(field.name_and_address[0], "JOHN DOE");
1004 assert_eq!(
1005 field.to_swift_string(),
1006 ":50:JOHN DOE\n123 MAIN ST\nNEW YORK"
1007 );
1008 }
1009
1010 #[test]
1011 fn test_field50a() {
1012 let field =
1013 Field50A::parse("/US123456789\n1/ACME CORP\n2/123 MAIN ST\n3/NEW YORK").unwrap();
1014 assert_eq!(field.party_identifier, Some("US123456789".to_string()));
1015 assert_eq!(field.name_and_address.len(), 3);
1016 assert_eq!(field.name_and_address[0], "ACME CORP");
1017
1018 let swift_str = field.to_swift_string();
1019 assert!(swift_str.starts_with(":50A:"));
1020 assert!(swift_str.contains("/US123456789"));
1021 assert!(swift_str.contains("1/ACME CORP"));
1022 }
1023
1024 #[test]
1025 fn test_field50f() {
1026 let field = Field50F::parse("ACCOUNT123\nDEUTDEFFXXX").unwrap();
1027 assert_eq!(field.account, "ACCOUNT123");
1028 assert_eq!(field.bic, "DEUTDEFFXXX");
1029 assert_eq!(field.to_swift_string(), ":50F:ACCOUNT123\nDEUTDEFFXXX");
1030 }
1031
1032 #[test]
1033 fn test_field50k() {
1034 let field = Field50K::parse(
1035 "/DE89370400440532013000\nJOHN DOE\n123 MAIN STREET\nNEW YORK NY 10001",
1036 )
1037 .unwrap();
1038 assert_eq!(field.account, Some("DE89370400440532013000".to_string()));
1039 assert_eq!(field.name_and_address[0], "JOHN DOE");
1040 assert_eq!(field.name_and_address.len(), 3);
1041 }
1042
1043 #[test]
1044 fn test_field50c() {
1045 let field = Field50C::parse("DEUTDEFF").unwrap();
1046 assert_eq!(field.bic, "DEUTDEFF");
1047 assert_eq!(field.to_swift_string(), ":50C:DEUTDEFF");
1048 }
1049
1050 #[test]
1051 fn test_field50l() {
1052 let field = Field50L::parse("PARTY123").unwrap();
1053 assert_eq!(field.party_identifier, "PARTY123");
1054 assert_eq!(field.to_swift_string(), ":50L:PARTY123");
1055 }
1056
1057 #[test]
1058 fn test_field50g() {
1059 let field = Field50G::parse("/ACCOUNT456\nCHASUS33XXX").unwrap();
1060 assert_eq!(field.account, "ACCOUNT456");
1061 assert_eq!(field.bic, "CHASUS33XXX");
1062 assert_eq!(field.to_swift_string(), ":50G:/ACCOUNT456\nCHASUS33XXX");
1063 }
1064
1065 #[test]
1066 fn test_field50h() {
1067 let field = Field50H::parse("/ACCOUNT789\nJANE SMITH\n456 ELM ST").unwrap();
1068 assert_eq!(field.account, "ACCOUNT789");
1069 assert_eq!(field.name_and_address.len(), 2);
1070 assert_eq!(field.name_and_address[0], "JANE SMITH");
1071 }
1072
1073 #[test]
1074 fn test_field50_ordering_customer_afk() {
1075 let field = Field50OrderingCustomerAFK::parse("1/ACME CORP\n2/NEW YORK").unwrap();
1077 assert!(matches!(field, Field50OrderingCustomerAFK::A(_)));
1078
1079 let field = Field50OrderingCustomerAFK::parse("/ACC123\nJOHN DOE").unwrap();
1081 assert!(matches!(field, Field50OrderingCustomerAFK::K(_)));
1082
1083 let field = Field50OrderingCustomerAFK::parse("ACCOUNT\nDEUTDEFF").unwrap();
1085 assert!(matches!(field, Field50OrderingCustomerAFK::F(_)));
1086 }
1087}