swift_mt_message/
traits.rs1use crate::{Result, SwiftResult};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::fmt::Debug;
7
8pub trait SwiftField: Serialize + for<'de> Deserialize<'de> + Clone + std::fmt::Debug {
10 fn parse(value: &str) -> Result<Self>
12 where
13 Self: Sized;
14
15 fn parse_with_variant(
18 value: &str,
19 _variant: Option<&str>,
20 _field_tag: Option<&str>,
21 ) -> Result<Self>
22 where
23 Self: Sized,
24 {
25 Self::parse(value)
26 }
27
28 fn to_swift_string(&self) -> String;
30
31 fn format_spec() -> &'static str;
33
34 fn valid_variants() -> Option<Vec<&'static str>> {
37 None }
39}
40
41pub trait SwiftMessageBody: Debug + Clone + Send + Sync + Serialize + std::any::Any {
43 fn message_type() -> &'static str;
45
46 fn from_fields(fields: HashMap<String, Vec<(String, usize)>>) -> SwiftResult<Self>
48 where
49 Self: Sized;
50
51 fn from_fields_with_config(
53 fields: HashMap<String, Vec<(String, usize)>>,
54 config: &crate::errors::ParserConfig,
55 ) -> std::result::Result<crate::errors::ParseResult<Self>, crate::errors::ParseError>
56 where
57 Self: Sized,
58 {
59 if config.fail_fast {
61 match Self::from_fields(fields) {
62 Ok(msg) => Ok(crate::errors::ParseResult::Success(msg)),
63 Err(e) => Err(e),
64 }
65 } else {
66 match Self::from_fields(fields) {
69 Ok(msg) => Ok(crate::errors::ParseResult::Success(msg)),
70 Err(e) => Err(e),
71 }
72 }
73 }
74
75 fn to_fields(&self) -> HashMap<String, Vec<String>>;
77
78 fn to_ordered_fields(&self) -> Vec<(String, String)> {
81 let field_map = self.to_fields();
83 let mut ordered_fields = Vec::new();
84
85 let mut field_tags: Vec<(&String, u32)> = field_map
88 .keys()
89 .map(|tag| {
90 let num = tag
91 .chars()
92 .take_while(|c| c.is_ascii_digit())
93 .fold(0u32, |acc, c| acc * 10 + (c as u32 - '0' as u32));
94 (tag, num)
95 })
96 .collect();
97 field_tags.sort_by(|(tag_a, num_a), (tag_b, num_b)| {
99 num_a.cmp(num_b).then_with(|| tag_a.cmp(tag_b))
100 });
101
102 for (field_tag, _) in field_tags {
104 if let Some(field_values) = field_map.get(field_tag) {
105 for field_value in field_values {
106 ordered_fields.push((field_tag.clone(), field_value.clone()));
107 }
108 }
109 }
110
111 ordered_fields
112 }
113
114 fn required_fields() -> Vec<&'static str>;
116
117 fn optional_fields() -> Vec<&'static str>;
119}