x12_stream_parser/
segment.rs1use std::fmt;
2
3#[derive(Clone, Copy, PartialEq, Eq)]
4pub struct SegmentSlice<'a> {
5 id: &'a [u8],
6 data: &'a [u8],
7 element_separator: u8,
8 sub_element_separator: u8,
9}
10
11impl<'a> SegmentSlice<'a> {
12 pub(crate) fn new(
13 full_segment: &'a [u8],
14 element_separator: u8,
15 sub_element_separator: u8,
16 ) -> Option<Self> {
17 if full_segment.is_empty() {
18 return None;
19 }
20
21 let id_end = full_segment
22 .iter()
23 .position(|&b| b == element_separator)
24 .unwrap_or(full_segment.len());
25
26 let id = &full_segment[..id_end];
27
28 if id.is_empty() {
29 return None; }
31
32 let data = if id_end < full_segment.len() {
33 &full_segment[id_end + 1..]
35 } else {
36 &full_segment[id_end..]
38 };
39
40
41 Some(SegmentSlice {
42 id,
43 data,
44 element_separator,
45 sub_element_separator,
46 })
47 }
48
49 pub fn id(&self) -> &'a [u8] {
50 self.id
51 }
52
53 pub fn elements(&self) -> ElementIterator<'a> {
54 ElementIterator {
55 remaining_data: self.data,
56 separator: self.element_separator,
57 }
58 }
59
60 pub fn element_separator(&self) -> u8 {
61 self.element_separator
62 }
63
64 pub fn sub_element_separator(&self) -> u8 {
65 self.sub_element_separator
66 }
67}
68
69impl<'a> fmt::Debug for SegmentSlice<'a> {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.debug_struct("SegmentSlice")
72 .field("id", &String::from_utf8_lossy(self.id))
73 .field("data", &String::from_utf8_lossy(self.data))
74 .field("element_separator", &(self.element_separator as char))
75 .field("sub_element_separator", &(self.sub_element_separator as char))
76 .finish()
77 }
78 }
79
80
81#[derive(Clone)]
82pub struct ElementIterator<'a> {
83 remaining_data: &'a [u8],
84 separator: u8,
85}
86
87impl<'a> Iterator for ElementIterator<'a> {
88 type Item = &'a [u8];
89
90 fn next(&mut self) -> Option<Self::Item> {
91 if self.remaining_data.is_empty() {
92 return None; }
99
100 let mut split_iter = self.remaining_data.splitn(2, |&b| b == self.separator);
101
102 let element = split_iter.next().unwrap_or_default(); self.remaining_data = split_iter.next().unwrap_or_else(|| &[]); Some(element)
106 }
107}
108
109pub fn split_sub_elements<'a>(element_data: &'a[u8], separator: u8) -> impl Iterator<Item = &'a [u8]> + Clone + 'a {
111 element_data.split(move |&b| b == separator)
112}