1use crate::EdifactError;
8use std::io::Write;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum EdifactEvent<'a> {
15 StartSegment {
17 tag: &'a str,
19 },
20 Element {
22 value: &'a str,
24 },
25 ComponentElement {
27 value: &'a str,
29 },
30 EndSegment,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
36pub enum OwnedEdifactEvent {
37 StartSegment {
39 tag: String,
41 },
42 Element {
44 value: String,
46 },
47 ComponentElement {
49 value: String,
51 },
52 EndSegment,
54}
55
56impl<'a> EdifactEvent<'a> {
57 pub fn into_owned(self) -> OwnedEdifactEvent {
59 match self {
60 Self::StartSegment { tag } => OwnedEdifactEvent::StartSegment {
61 tag: tag.to_owned(),
62 },
63 Self::Element { value } => OwnedEdifactEvent::Element {
64 value: value.to_owned(),
65 },
66 Self::ComponentElement { value } => OwnedEdifactEvent::ComponentElement {
67 value: value.to_owned(),
68 },
69 Self::EndSegment => OwnedEdifactEvent::EndSegment,
70 }
71 }
72}
73
74pub trait EventEmitter {
78 fn emit(&mut self, event: EdifactEvent<'_>) -> Result<(), EdifactError>;
80}
81
82#[derive(Debug, Default)]
88pub struct VecEmitter {
89 pub events: Vec<OwnedEdifactEvent>,
91}
92
93impl EventEmitter for VecEmitter {
94 fn emit(&mut self, event: EdifactEvent<'_>) -> Result<(), EdifactError> {
95 self.events.push(event.into_owned());
96 Ok(())
97 }
98}
99
100pub struct WriterEmitter<W: Write> {
116 writer: crate::Writer<W>,
117}
118
119impl<W: Write> WriterEmitter<W> {
120 pub fn new(inner: W) -> Self {
122 Self {
123 writer: crate::Writer::new(inner),
124 }
125 }
126
127 pub fn finish(self) -> Result<W, EdifactError> {
129 self.writer.finish()
130 }
131
132 pub fn segment_count(&self) -> u32 {
134 self.writer.segment_count()
135 }
136}
137
138impl<W: Write> EventEmitter for WriterEmitter<W> {
139 fn emit(&mut self, event: EdifactEvent<'_>) -> Result<(), EdifactError> {
140 match event {
141 EdifactEvent::StartSegment { tag } => {
142 self.writer.write_tag_only(tag)?;
143 }
144 EdifactEvent::Element { value } => {
145 self.writer.write_element_sep()?;
146 self.writer.write_escaped(value)?;
147 }
148 EdifactEvent::ComponentElement { value } => {
149 self.writer.write_component_sep()?;
150 self.writer.write_escaped(value)?;
151 }
152 EdifactEvent::EndSegment => {
153 self.writer.write_segment_term_and_count()?;
154 }
155 }
156 Ok(())
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163
164 #[test]
165 fn vec_emitter_no_memory_leak() {
166 let mut e = VecEmitter::default();
167 e.emit(EdifactEvent::StartSegment { tag: "BGM" }).unwrap();
168 e.emit(EdifactEvent::Element { value: "E03" }).unwrap();
169 e.emit(EdifactEvent::EndSegment).unwrap();
170 assert_eq!(
171 e.events[0],
172 OwnedEdifactEvent::StartSegment {
173 tag: "BGM".to_owned()
174 }
175 );
176 assert_eq!(
177 e.events[1],
178 OwnedEdifactEvent::Element {
179 value: "E03".to_owned()
180 }
181 );
182 }
183
184 #[test]
185 fn writer_emitter_produces_valid_edifact() {
186 let mut buf = Vec::new();
187 {
188 let mut e = WriterEmitter::new(&mut buf);
189 e.emit(EdifactEvent::StartSegment { tag: "BGM" }).unwrap();
190 e.emit(EdifactEvent::Element { value: "E03" }).unwrap();
191 e.emit(EdifactEvent::Element { value: "11042" }).unwrap();
192 e.emit(EdifactEvent::EndSegment).unwrap();
193 e.finish().unwrap();
194 }
195 assert_eq!(buf, b"BGM+E03+11042'");
196 }
197
198 #[test]
199 fn writer_emitter_handles_components() {
200 let mut buf = Vec::new();
201 {
202 let mut e = WriterEmitter::new(&mut buf);
203 e.emit(EdifactEvent::StartSegment { tag: "NAD" }).unwrap();
204 e.emit(EdifactEvent::Element { value: "MS" }).unwrap();
205 e.emit(EdifactEvent::Element {
206 value: "9900112233445",
207 })
208 .unwrap();
209 e.emit(EdifactEvent::ComponentElement { value: "" })
210 .unwrap();
211 e.emit(EdifactEvent::ComponentElement { value: "293" })
212 .unwrap();
213 e.emit(EdifactEvent::EndSegment).unwrap();
214 e.finish().unwrap();
215 }
216 let s = std::str::from_utf8(&buf).unwrap();
217 assert_eq!(s, "NAD+MS+9900112233445::293'");
218 }
219}