1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, Serialize, Deserialize)]
5#[serde(rename_all = "camelCase")]
6pub struct Interchangedaten {
7 pub syntax_kennung: Option<String>,
8 pub absender_code: Option<String>,
9 pub empfaenger_code: Option<String>,
10 pub datum: Option<String>,
11 pub zeit: Option<String>,
12 pub interchange_ref: Option<String>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct Nachrichtendaten {
19 pub unh_referenz: String,
20 pub nachrichten_typ: String,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct Interchange<M, T> {
27 pub interchangedaten: Interchangedaten,
28 pub nachrichten: Vec<Nachricht<M, T>>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
33#[serde(rename_all = "camelCase")]
34pub struct Nachricht<M, T> {
35 pub nachrichtendaten: Nachrichtendaten,
36 pub stammdaten: M,
37 pub transaktionen: Vec<T>,
38}
39
40pub type DynamicInterchange = Interchange<serde_json::Value, serde_json::Value>;
42pub type DynamicNachricht = Nachricht<serde_json::Value, serde_json::Value>;
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use serde_json::json;
49
50 #[test]
51 fn test_dynamic_interchange_serde_roundtrip() {
52 let interchange: DynamicInterchange = Interchange {
53 interchangedaten: Interchangedaten {
54 syntax_kennung: Some("UNOC".to_string()),
55 absender_code: Some("1234567890123".to_string()),
56 empfaenger_code: Some("9876543210987".to_string()),
57 datum: Some("20260326".to_string()),
58 zeit: Some("1430".to_string()),
59 interchange_ref: Some("00001".to_string()),
60 },
61 nachrichten: vec![Nachricht {
62 nachrichtendaten: Nachrichtendaten {
63 unh_referenz: "00001".to_string(),
64 nachrichten_typ: "UTILMD".to_string(),
65 },
66 stammdaten: json!({"key": "value"}),
67 transaktionen: vec![json!({"tx": 1}), json!({"tx": 2})],
68 }],
69 };
70
71 let json_str = serde_json::to_string(&interchange).unwrap();
72 let deserialized: DynamicInterchange = serde_json::from_str(&json_str).unwrap();
73
74 assert_eq!(
75 deserialized.interchangedaten.syntax_kennung,
76 Some("UNOC".to_string())
77 );
78 assert_eq!(
79 deserialized.interchangedaten.absender_code,
80 Some("1234567890123".to_string())
81 );
82 assert_eq!(
83 deserialized.interchangedaten.empfaenger_code,
84 Some("9876543210987".to_string())
85 );
86 assert_eq!(deserialized.nachrichten.len(), 1);
87 assert_eq!(
88 deserialized.nachrichten[0].nachrichtendaten.unh_referenz,
89 "00001"
90 );
91 assert_eq!(
92 deserialized.nachrichten[0].nachrichtendaten.nachrichten_typ,
93 "UTILMD"
94 );
95 assert_eq!(
96 deserialized.nachrichten[0].stammdaten,
97 json!({"key": "value"})
98 );
99 assert_eq!(deserialized.nachrichten[0].transaktionen.len(), 2);
100 }
101
102 #[test]
103 fn test_typed_interchange_serde_roundtrip() {
104 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
105 struct TestStamm {
106 name: String,
107 }
108
109 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
110 struct TestTx {
111 id: u32,
112 }
113
114 let interchange: Interchange<TestStamm, TestTx> = Interchange {
115 interchangedaten: Interchangedaten::default(),
116 nachrichten: vec![Nachricht {
117 nachrichtendaten: Nachrichtendaten {
118 unh_referenz: "REF1".to_string(),
119 nachrichten_typ: "ORDERS".to_string(),
120 },
121 stammdaten: TestStamm {
122 name: "test".to_string(),
123 },
124 transaktionen: vec![TestTx { id: 1 }, TestTx { id: 2 }],
125 }],
126 };
127
128 let json_str = serde_json::to_string(&interchange).unwrap();
129 let deserialized: Interchange<TestStamm, TestTx> = serde_json::from_str(&json_str).unwrap();
130
131 assert_eq!(deserialized.nachrichten.len(), 1);
132 assert_eq!(
133 deserialized.nachrichten[0].stammdaten,
134 TestStamm {
135 name: "test".to_string()
136 }
137 );
138 assert_eq!(deserialized.nachrichten[0].transaktionen.len(), 2);
139 assert_eq!(
140 deserialized.nachrichten[0].transaktionen[0],
141 TestTx { id: 1 }
142 );
143 assert_eq!(
144 deserialized.nachrichten[0].transaktionen[1],
145 TestTx { id: 2 }
146 );
147 }
148
149 #[test]
150 fn test_interchangedaten_camel_case_serialization() {
151 let data = Interchangedaten {
152 syntax_kennung: Some("UNOC".to_string()),
153 absender_code: Some("SENDER".to_string()),
154 empfaenger_code: None,
155 datum: None,
156 zeit: None,
157 interchange_ref: Some("REF".to_string()),
158 };
159
160 let json_value: serde_json::Value = serde_json::to_value(&data).unwrap();
161 let obj = json_value.as_object().unwrap();
162
163 assert!(obj.contains_key("syntaxKennung"));
165 assert!(obj.contains_key("absenderCode"));
166 assert!(obj.contains_key("empfaengerCode"));
167 assert!(obj.contains_key("datum"));
168 assert!(obj.contains_key("zeit"));
169 assert!(obj.contains_key("interchangeRef"));
170
171 assert!(!obj.contains_key("syntax_kennung"));
173 assert!(!obj.contains_key("absender_code"));
174 assert!(!obj.contains_key("empfaenger_code"));
175 assert!(!obj.contains_key("interchange_ref"));
176 }
177}