1
2use crate::{
3 ParseIterator,
4 position::Position,
5 pit::PointInTime
6};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct Recorder {
10 pos: Position
11}
12
13impl Recorder {
14
15 pub(super) fn new(pos: Position) -> Self {
16 Self {pos}
17 }
18
19 pub fn pos(&self) -> Position {
20 self.pos
21 }
22
23}
24
25
26#[derive(Debug)]
27pub struct RecordIter<'a, T> {
28 inner: &'a mut T,
29 recorder: Recorder
30}
31
32impl<'s, 'a, T> RecordIter<'a, T>
33where T: ParseIterator<'s> {
34 pub(super) fn new(inner: &'a mut T) -> Self {
35 let pos = inner.pit().record_pos();
36 Self {
37 inner,
38 recorder: Recorder::new(pos)
39 }
40 }
41}
42
43
44impl<'s, 'a, T> ParseIterator<'s> for RecordIter<'a, T>
45where T: ParseIterator<'s> {
46
47 type PointInTime = T::PointInTime;
48
49 fn slice(&self) -> &'s [u8] {
50 self.inner.slice()
51 }
52
53 fn pit(&self) -> Self::PointInTime {
54 self.inner.pit()
55 }
56
57 fn restore_pit(&mut self, pit: Self::PointInTime) {
58 self.inner.restore_pit(pit)
59 }
60
61 fn advance(&mut self) -> Option<()> {
62 self.inner.advance()
63 }
64
65 fn recorder(&self) -> Option<&Recorder> {
66 Some(&self.recorder)
67 }
68
69 #[inline]
74 unsafe fn is_valid_utf8() -> bool {
75 T::is_valid_utf8()
76 }
77
78}
79
80
81
82#[cfg(test)]
83mod tests {
84
85 use crate::*;
86
87 #[test]
88 fn record() {
89
90 let s = b"my byte str";
91
92 let mut parser = Parser::new( s );
93 parser.consume_while_byte_fn( |&b| b != b' ' )
94 .next().unwrap();unsafe {
97 let st = parser.record()
98 .consume_to_str_unchecked();
99
100 assert_eq!( "byte str", st );
101 }
102
103 }
104
105 #[test]
106 fn record_combi() {
107
108 let s = b"my byte str";
109
110 let mut parser = Parser::new( s );
111 let mut parser = parser.split_on_byte( b' ' );
112
113 unsafe {
114 let st = parser.next().unwrap()
115 .record()
116 .consume_to_str_unchecked();
117
118 assert_eq!( "my", st );
119
120 let st = parser.next().unwrap()
121 .record()
122 .consume_to_str_unchecked();
123
124 assert_eq!( "byte", st );
125 }
126
127 }
128
129 #[test]
130 fn nested_record() {
131
132 let s = b"aaaabbb";
133
134 let mut parser = Parser::new( s );
135
136 let mut first_recorder = parser.record();
137
138 unsafe {
139 let res = first_recorder
140 .while_byte_fn( |&b| b == b'a' )
141 .record()
142 .consume_to_str_unchecked();
143 assert_eq!( "aaaa", res );
144 }
145
146 unsafe {
147 assert_eq!( "aaaabbb", first_recorder.consume_to_str_unchecked() );
148 }
149
150 }
151
152 #[test]
153 fn check_that_it_is_inplace() {
154
155 let mut parser = Parser::new( b"aaaabbb" );
156
157 unsafe {
158 let res = parser
159 .record()
160 .consume_while_byte_fn( |&b| b == b'a' )
161 .to_str_unchecked();
162 assert_eq!( "aaaa", res );
163 }
164
165 }
166
167}