winnow/stream/
token.rs
1use crate::error::Needed;
2use crate::lib::std::iter::Enumerate;
3use crate::lib::std::slice::Iter;
4use crate::stream::Checkpoint;
5use crate::stream::Compare;
6use crate::stream::CompareResult;
7use crate::stream::Location;
8use crate::stream::Offset;
9#[cfg(feature = "unstable-recover")]
10#[cfg(feature = "std")]
11use crate::stream::Recover;
12use crate::stream::SliceLen;
13use crate::stream::Stream;
14use crate::stream::StreamIsPartial;
15use crate::stream::UpdateSlice;
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq)]
26pub struct TokenSlice<'t, T> {
27 initial: &'t [T],
28 input: &'t [T],
29}
30
31impl<'t, T> TokenSlice<'t, T>
32where
33 T: crate::lib::std::fmt::Debug + Clone,
34{
35 #[inline]
37 pub fn new(input: &'t [T]) -> Self {
38 Self {
39 initial: input,
40 input,
41 }
42 }
43
44 #[doc(alias = "fseek")]
49 #[inline]
50 pub fn reset_to_start(&mut self) {
51 let start = self.initial.checkpoint();
52 self.input.reset(&start);
53 }
54}
55
56impl<T> TokenSlice<'_, T>
58where
59 T: Location,
60{
61 #[inline(always)]
62 fn previous_token_end(&self) -> Option<usize> {
63 let index = self.input.offset_from(&self.initial);
64 index
65 .checked_sub(1)
66 .map(|i| self.initial[i].previous_token_end())
67 }
68
69 #[inline(always)]
70 fn current_token_start(&self) -> Option<usize> {
71 self.input.first().map(|t| t.current_token_start())
72 }
73}
74
75impl<T> Default for TokenSlice<'_, T>
76where
77 T: crate::lib::std::fmt::Debug + Clone,
78{
79 fn default() -> Self {
80 Self::new(&[])
81 }
82}
83
84impl<T> crate::lib::std::ops::Deref for TokenSlice<'_, T> {
85 type Target = [T];
86
87 fn deref(&self) -> &Self::Target {
88 self.input
89 }
90}
91
92impl<T> SliceLen for TokenSlice<'_, T> {
93 #[inline(always)]
94 fn slice_len(&self) -> usize {
95 self.input.slice_len()
96 }
97}
98
99impl<'t, T> Stream for TokenSlice<'t, T>
100where
101 T: crate::lib::std::fmt::Debug + Clone,
102{
103 type Token = &'t T;
104 type Slice = &'t [T];
105
106 type IterOffsets = Enumerate<Iter<'t, T>>;
107
108 type Checkpoint = Checkpoint<&'t [T], Self>;
109
110 #[inline(always)]
111 fn iter_offsets(&self) -> Self::IterOffsets {
112 self.input.iter().enumerate()
113 }
114 #[inline(always)]
115 fn eof_offset(&self) -> usize {
116 self.input.eof_offset()
117 }
118
119 #[inline(always)]
120 fn next_token(&mut self) -> Option<Self::Token> {
121 let (token, next) = self.input.split_first()?;
122 self.input = next;
123 Some(token)
124 }
125
126 #[inline(always)]
127 fn peek_token(&self) -> Option<Self::Token> {
128 self.input.first()
129 }
130
131 #[inline(always)]
132 fn offset_for<P>(&self, predicate: P) -> Option<usize>
133 where
134 P: Fn(Self::Token) -> bool,
135 {
136 self.input.iter().position(predicate)
137 }
138 #[inline(always)]
139 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
140 self.input.offset_at(tokens)
141 }
142 #[inline(always)]
143 fn next_slice(&mut self, offset: usize) -> Self::Slice {
144 self.input.next_slice(offset)
145 }
146 #[inline(always)]
147 fn peek_slice(&self, offset: usize) -> Self::Slice {
148 self.input.peek_slice(offset)
149 }
150
151 #[inline(always)]
152 fn checkpoint(&self) -> Self::Checkpoint {
153 Checkpoint::<_, Self>::new(self.input)
154 }
155 #[inline(always)]
156 fn reset(&mut self, checkpoint: &Self::Checkpoint) {
157 self.input = checkpoint.inner;
158 }
159
160 #[inline(always)]
161 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
162 &self.input
163 }
164}
165
166impl<T> Location for TokenSlice<'_, T>
167where
168 T: Location,
169{
170 #[inline(always)]
171 fn previous_token_end(&self) -> usize {
172 self.previous_token_end()
173 .or_else(|| self.current_token_start())
174 .unwrap_or(0)
175 }
176 #[inline(always)]
177 fn current_token_start(&self) -> usize {
178 self.current_token_start()
179 .or_else(|| self.previous_token_end())
180 .unwrap_or(0)
181 }
182}
183
184#[cfg(feature = "unstable-recover")]
185#[cfg(feature = "std")]
186impl<T, E> Recover<E> for TokenSlice<'_, T>
187where
188 T: crate::lib::std::fmt::Debug + Clone,
189{
190 #[inline(always)]
191 fn record_err(
192 &mut self,
193 _token_start: &Self::Checkpoint,
194 _err_start: &Self::Checkpoint,
195 err: E,
196 ) -> Result<(), E> {
197 Err(err)
198 }
199
200 #[inline(always)]
202 fn is_recovery_supported() -> bool {
203 false
204 }
205}
206
207impl<'t, T> StreamIsPartial for TokenSlice<'t, T>
208where
209 T: crate::lib::std::fmt::Debug + Clone,
210{
211 type PartialState = <&'t [T] as StreamIsPartial>::PartialState;
212
213 #[inline]
214 fn complete(&mut self) -> Self::PartialState {
215 #![allow(clippy::semicolon_if_nothing_returned)]
216 self.input.complete()
217 }
218
219 #[inline]
220 fn restore_partial(&mut self, state: Self::PartialState) {
221 self.input.restore_partial(state);
222 }
223
224 #[inline(always)]
225 fn is_partial_supported() -> bool {
226 <&[T] as StreamIsPartial>::is_partial_supported()
227 }
228
229 #[inline(always)]
230 fn is_partial(&self) -> bool {
231 self.input.is_partial()
232 }
233}
234
235impl<T> Offset for TokenSlice<'_, T>
236where
237 T: crate::lib::std::fmt::Debug + Clone,
238{
239 #[inline(always)]
240 fn offset_from(&self, other: &Self) -> usize {
241 self.offset_from(&other.checkpoint())
242 }
243}
244
245impl<T> Offset<<TokenSlice<'_, T> as Stream>::Checkpoint> for TokenSlice<'_, T>
246where
247 T: crate::lib::std::fmt::Debug + Clone,
248{
249 #[inline(always)]
250 fn offset_from(&self, other: &<TokenSlice<'_, T> as Stream>::Checkpoint) -> usize {
251 self.checkpoint().offset_from(other)
252 }
253}
254
255impl<T, O> Compare<O> for TokenSlice<'_, T>
256where
257 T: PartialEq<O> + Eq,
258{
259 #[inline]
260 fn compare(&self, t: O) -> CompareResult {
261 if let Some(token) = self.first() {
262 if *token == t {
263 CompareResult::Ok(1)
264 } else {
265 CompareResult::Error
266 }
267 } else {
268 CompareResult::Incomplete
269 }
270 }
271}
272
273impl<T> UpdateSlice for TokenSlice<'_, T>
274where
275 T: crate::lib::std::fmt::Debug + Clone,
276{
277 #[inline(always)]
278 fn update_slice(mut self, inner: Self::Slice) -> Self {
279 self.input = <&[T] as UpdateSlice>::update_slice(self.input, inner);
280 self
281 }
282}