x12_stream_parser/parser.rs
1use crate::errors::ParserError;
2use crate::segment::SegmentSlice;
3use x12_delimiters::Delimiters;
4
5#[derive(Clone)]
6pub struct Parser<'a> {
7 remaining_input: &'a [u8],
8 delimiters: Delimiters,
9 finished: bool, // Track if iteration is truly finished vs. just hit end of buffer temporarily
10}
11
12impl<'a> Parser<'a> {
13 pub fn new(input: &'a [u8], delimiters: Delimiters) -> Self {
14 Parser {
15 remaining_input: input,
16 delimiters,
17 finished: false,
18 }
19 }
20}
21
22impl<'a> Iterator for Parser<'a> {
23 type Item = Result<SegmentSlice<'a>, ParserError>;
24
25 fn next(&mut self) -> Option<Self::Item> {
26 if self.finished {
27 return None;
28 }
29
30 let terminator = self.delimiters.segment_terminator();
31
32 match self
33 .remaining_input
34 .iter()
35 .position(|&b| b == terminator)
36 {
37 Some(term_pos) => {
38 let segment_data = &self.remaining_input[..term_pos];
39 // Advance past segment including terminator for next iteration
40 self.remaining_input = &self.remaining_input[term_pos + 1..];
41
42 if segment_data.is_empty() {
43 // Skip empty segments often caused by trailing terminators? Or return error?
44 // Let's skip them. User might have input like "ISA*...~GS*...~~ST*..."
45 // Recurse to find the next valid segment.
46 // Avoid recursion depth issues: loop instead.
47 // Actually, let's just return None if the segment_data is empty after a split.
48 // This means consecutive terminators end the iteration.
49 if self.remaining_input.is_empty() {
50 self.finished = true;
51 }
52 return self.next(); // Try again with advanced input
53 }
54
55 match SegmentSlice::new(
56 segment_data,
57 self.delimiters.element_separator(),
58 self.delimiters.sub_element_separator(),
59 ) {
60 Some(segment_slice) => {
61 if self.remaining_input.is_empty() {
62 self.finished = true; // Mark finished if we consumed the rest
63 }
64 Some(Ok(segment_slice))
65 },
66 None => {
67 // SegmentSlice::new returns None if segment_data is empty or ID is empty.
68 // We already checked for empty segment_data. So this means empty ID.
69 self.finished = true; // Stop iteration on error
70 Some(Err(ParserError::SegmentIdNotFound))
71 }
72 }
73 }
74 None => {
75 self.finished = true; // Mark as finished
76 // If there's remaining data, it's an error (unterminated)
77 if self.remaining_input.is_empty() {
78 None // Normal end of iteration
79 } else {
80 Some(Err(ParserError::UnterminatedSegment))
81 }
82 }
83 }
84 }
85}