1use crate::EdifactError;
8use crate::event::{EdifactEvent, EventEmitter, WriterEmitter};
9use std::io::Write;
10
11pub trait EdifactSerialize {
18 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError>;
20}
21
22pub trait EdifactCompositeSerialize {
27 fn edifact_serialize_composite<E: EventEmitter>(
29 &self,
30 emitter: &mut E,
31 ) -> Result<(), EdifactError>;
32}
33
34impl EdifactCompositeSerialize for Vec<String> {
35 fn edifact_serialize_composite<E: EventEmitter>(
36 &self,
37 emitter: &mut E,
38 ) -> Result<(), EdifactError> {
39 if self.is_empty() {
40 return emitter.emit(EdifactEvent::Element { value: "" });
41 }
42
43 emitter.emit(EdifactEvent::Element { value: &self[0] })?;
44 for component in self.iter().skip(1) {
45 emitter.emit(EdifactEvent::ComponentElement { value: component })?;
46 }
47 Ok(())
48 }
49}
50
51impl EdifactSerialize for str {
54 #[inline]
55 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
56 emitter.emit(EdifactEvent::Element { value: self })
57 }
58}
59
60impl EdifactSerialize for String {
61 #[inline]
62 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
63 emitter.emit(EdifactEvent::Element {
64 value: self.as_str(),
65 })
66 }
67}
68
69impl<T: EdifactSerialize> EdifactSerialize for Option<T> {
71 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
72 match self {
73 Some(v) => v.edifact_serialize(emitter),
74 None => emitter.emit(EdifactEvent::Element { value: "" }),
75 }
76 }
77}
78
79impl<T: EdifactSerialize> EdifactSerialize for Vec<T> {
81 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
82 for item in self {
83 item.edifact_serialize(emitter)?;
84 }
85 Ok(())
86 }
87}
88
89impl<T: EdifactSerialize> EdifactSerialize for [T] {
91 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
92 for item in self {
93 item.edifact_serialize(emitter)?;
94 }
95 Ok(())
96 }
97}
98
99macro_rules! impl_serialize_int {
100 ($($t:ty),+ $(,)?) => {
101 $(
102 impl EdifactSerialize for $t {
103 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
104 use std::io::Write as _;
106 let mut buf = [0u8; 42];
107 let mut w: &mut [u8] = &mut buf;
108 if write!(w, "{self}").is_ok() {
109 let written = 42 - w.len();
110 let s = std::str::from_utf8(&buf[..written]).map_err(|_| EdifactError::InvalidUtf8)?;
112 emitter.emit(EdifactEvent::Element { value: s })
113 } else {
114 let s = format!("{self}");
116 emitter.emit(EdifactEvent::Element { value: &s })
117 }
118 }
119 }
120 )+
121 };
122}
123
124impl_serialize_int!(
126 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, bool
127);
128
129macro_rules! impl_serialize_float {
141 ($($t:ty),+ $(,)?) => {
142 $(
143 impl EdifactSerialize for $t {
144 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
145 use std::io::Write as _;
146 let mut buf = [0u8; 320];
147 let mut w: &mut [u8] = &mut buf;
148 if write!(w, "{self}").is_ok() {
149 let written = 320 - w.len();
150 let s = std::str::from_utf8(&buf[..written]).map_err(|_| EdifactError::InvalidUtf8)?;
152 emitter.emit(EdifactEvent::Element { value: s })
153 } else {
154 let s = format!("{self}");
156 emitter.emit(EdifactEvent::Element { value: &s })
157 }
158 }
159 }
160 )+
161 };
162}
163
164impl_serialize_float!(f32, f64);
165
166pub fn to_writer<T, W>(inner: W, value: &T) -> Result<(), EdifactError>
170where
171 T: EdifactSerialize,
172 W: Write,
173{
174 let mut emitter = WriterEmitter::new(inner);
175 value.edifact_serialize(&mut emitter)?;
176 emitter.finish().map(|_| ())
177}
178
179pub fn to_bytes<T: EdifactSerialize>(value: &T) -> Result<Vec<u8>, EdifactError> {
181 let mut buf = Vec::new();
182 to_writer(&mut buf, value)?;
183 Ok(buf)
184}
185
186pub fn to_edifact_string<T: EdifactSerialize>(value: &T) -> Result<String, EdifactError> {
195 let bytes = to_bytes(value)?;
196 String::from_utf8(bytes).map_err(|_| EdifactError::InvalidUtf8)
197}
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202 use crate::event::{OwnedEdifactEvent, VecEmitter};
203
204 struct BgmSegment {
205 doc_name_code: String,
206 pruef_id: String,
207 msg_function: Option<String>,
208 }
209
210 impl EdifactSerialize for BgmSegment {
211 fn edifact_serialize<E: EventEmitter>(&self, emitter: &mut E) -> Result<(), EdifactError> {
212 emitter.emit(EdifactEvent::StartSegment { tag: "BGM" })?;
213 emitter.emit(EdifactEvent::Element {
214 value: &self.doc_name_code,
215 })?;
216 emitter.emit(EdifactEvent::Element {
217 value: &self.pruef_id,
218 })?;
219 self.msg_function.edifact_serialize(emitter)?;
220 emitter.emit(EdifactEvent::EndSegment)?;
221 Ok(())
222 }
223 }
224
225 #[test]
226 fn vec_emitter_captures_segment_events() {
227 let seg = BgmSegment {
228 doc_name_code: "E03".to_owned(),
229 pruef_id: "11042".to_owned(),
230 msg_function: None,
231 };
232 let mut emitter = VecEmitter::default();
233 seg.edifact_serialize(&mut emitter).unwrap();
234
235 assert_eq!(
236 emitter.events[0],
237 OwnedEdifactEvent::StartSegment {
238 tag: "BGM".to_owned()
239 }
240 );
241 assert_eq!(emitter.events.last(), Some(&OwnedEdifactEvent::EndSegment));
242 }
243
244 #[test]
245 fn to_bytes_produces_valid_edifact() {
246 let seg = BgmSegment {
247 doc_name_code: "E03".to_owned(),
248 pruef_id: "11042".to_owned(),
249 msg_function: Some("9".to_owned()),
250 };
251 let bytes = to_bytes(&seg).unwrap();
252 assert_eq!(std::str::from_utf8(&bytes).unwrap(), "BGM+E03+11042+9'");
253 }
254
255 #[test]
256 fn option_none_emits_empty_element() {
257 let val: Option<String> = None;
258 let mut emitter = VecEmitter::default();
259 val.edifact_serialize(&mut emitter).unwrap();
260 assert_eq!(
261 emitter.events[0],
262 OwnedEdifactEvent::Element {
263 value: String::new()
264 }
265 );
266 }
267
268 #[test]
269 fn option_some_emits_value() {
270 let val: Option<String> = Some("TEST".to_owned());
271 let mut emitter = VecEmitter::default();
272 val.edifact_serialize(&mut emitter).unwrap();
273 assert_eq!(
274 emitter.events[0],
275 OwnedEdifactEvent::Element {
276 value: "TEST".to_owned()
277 }
278 );
279 }
280
281 #[test]
282 fn integer_types_serialize_without_alloc() {
283 let mut emitter = VecEmitter::default();
284 42u32.edifact_serialize(&mut emitter).unwrap();
285 assert_eq!(
286 emitter.events[0],
287 OwnedEdifactEvent::Element {
288 value: "42".to_owned()
289 }
290 );
291 let mut emitter2 = VecEmitter::default();
293 i128::MIN.edifact_serialize(&mut emitter2).unwrap();
294 assert_eq!(
295 emitter2.events[0],
296 OwnedEdifactEvent::Element {
297 value: "-170141183460469231731687303715884105728".to_owned()
298 }
299 );
300 }
301
302 #[test]
303 fn float_extremes_do_not_panic() {
304 let mut emitter = VecEmitter::default();
306 f64::MAX.edifact_serialize(&mut emitter).unwrap();
307 let s = match &emitter.events[0] {
308 OwnedEdifactEvent::Element { value } => value.clone(),
309 _ => panic!("expected Element event"),
310 };
311 assert!(!s.is_empty());
312 let mut emitter2 = VecEmitter::default();
314 f32::MAX.edifact_serialize(&mut emitter2).unwrap();
315 assert!(matches!(&emitter2.events[0], OwnedEdifactEvent::Element { .. }));
316 }
317
318 #[test]
319 fn vec_serializes_each_item() {
320 let segments = vec![
321 BgmSegment {
322 doc_name_code: "E03".to_owned(),
323 pruef_id: "11042".to_owned(),
324 msg_function: None,
325 },
326 BgmSegment {
327 doc_name_code: "E01".to_owned(),
328 pruef_id: "11043".to_owned(),
329 msg_function: None,
330 },
331 ];
332 let bytes = to_bytes(&segments).unwrap();
333 let s = std::str::from_utf8(&bytes).unwrap();
334 assert!(s.contains("BGM+E03+11042"));
335 assert!(s.contains("BGM+E01+11043"));
336 }
337}