winnow/stream/
locating.rs1use crate::stream::AsBStr;
2use crate::stream::AsBytes;
3use crate::stream::Checkpoint;
4use crate::stream::Compare;
5use crate::stream::CompareResult;
6use crate::stream::FindSlice;
7use crate::stream::Location;
8use crate::stream::Needed;
9use crate::stream::Offset;
10#[cfg(feature = "unstable-recover")]
11#[cfg(feature = "std")]
12use crate::stream::Recover;
13use crate::stream::SliceLen;
14use crate::stream::Stream;
15use crate::stream::StreamIsPartial;
16use crate::stream::UpdateSlice;
17
18#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
29#[doc(alias = "LocatingSliceSpan")]
30#[doc(alias = "Located")]
31pub struct LocatingSlice<I> {
32 initial: I,
33 input: I,
34}
35
36impl<I> LocatingSlice<I>
37where
38 I: Clone + Offset,
39{
40 pub fn new(input: I) -> Self {
42 let initial = input.clone();
43 Self { initial, input }
44 }
45
46 #[inline]
47 fn previous_token_end(&self) -> usize {
48 self.input.offset_from(&self.initial)
52 }
53 #[inline]
54 fn current_token_start(&self) -> usize {
55 self.input.offset_from(&self.initial)
58 }
59}
60
61impl<I> LocatingSlice<I>
62where
63 I: Clone + Stream + Offset,
64{
65 #[doc(alias = "fseek")]
70 #[inline]
71 pub fn reset_to_start(&mut self) {
72 let start = self.initial.checkpoint();
73 self.input.reset(&start);
74 }
75}
76
77impl<I> AsRef<I> for LocatingSlice<I> {
78 #[inline(always)]
79 fn as_ref(&self) -> &I {
80 &self.input
81 }
82}
83
84impl<I: core::fmt::Debug> core::fmt::Debug for LocatingSlice<I> {
85 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
86 self.input.fmt(f)
87 }
88}
89
90impl<I> core::ops::Deref for LocatingSlice<I> {
91 type Target = I;
92
93 #[inline(always)]
94 fn deref(&self) -> &Self::Target {
95 &self.input
96 }
97}
98
99impl<I: core::fmt::Display> core::fmt::Display for LocatingSlice<I> {
100 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
101 self.input.fmt(f)
102 }
103}
104
105impl<I> SliceLen for LocatingSlice<I>
106where
107 I: SliceLen,
108{
109 #[inline(always)]
110 fn slice_len(&self) -> usize {
111 self.input.slice_len()
112 }
113}
114
115impl<I: Stream> Stream for LocatingSlice<I> {
116 type Token = <I as Stream>::Token;
117 type Slice = <I as Stream>::Slice;
118
119 type IterOffsets = <I as Stream>::IterOffsets;
120
121 type Checkpoint = Checkpoint<I::Checkpoint, Self>;
122
123 #[inline(always)]
124 fn iter_offsets(&self) -> Self::IterOffsets {
125 self.input.iter_offsets()
126 }
127 #[inline(always)]
128 fn eof_offset(&self) -> usize {
129 self.input.eof_offset()
130 }
131
132 #[inline(always)]
133 fn next_token(&mut self) -> Option<Self::Token> {
134 self.input.next_token()
135 }
136
137 #[inline(always)]
138 fn peek_token(&self) -> Option<Self::Token> {
139 self.input.peek_token()
140 }
141
142 #[inline(always)]
143 fn offset_for<P>(&self, predicate: P) -> Option<usize>
144 where
145 P: Fn(Self::Token) -> bool,
146 {
147 self.input.offset_for(predicate)
148 }
149 #[inline(always)]
150 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
151 self.input.offset_at(tokens)
152 }
153 #[inline(always)]
154 fn next_slice(&mut self, offset: usize) -> Self::Slice {
155 self.input.next_slice(offset)
156 }
157 #[inline(always)]
158 unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
159 unsafe { self.input.next_slice_unchecked(offset) }
161 }
162 #[inline(always)]
163 fn peek_slice(&self, offset: usize) -> Self::Slice {
164 self.input.peek_slice(offset)
165 }
166 #[inline(always)]
167 unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
168 unsafe { self.input.peek_slice_unchecked(offset) }
170 }
171
172 #[inline(always)]
173 fn checkpoint(&self) -> Self::Checkpoint {
174 Checkpoint::<_, Self>::new(self.input.checkpoint())
175 }
176 #[inline(always)]
177 fn reset(&mut self, checkpoint: &Self::Checkpoint) {
178 self.input.reset(&checkpoint.inner);
179 }
180
181 fn trace(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
182 self.input.trace(f)
183 }
184}
185
186impl<I> Location for LocatingSlice<I>
187where
188 I: Clone + Offset,
189{
190 #[inline(always)]
191 fn previous_token_end(&self) -> usize {
192 self.previous_token_end()
193 }
194 #[inline(always)]
195 fn current_token_start(&self) -> usize {
196 self.current_token_start()
197 }
198}
199
200#[cfg(feature = "unstable-recover")]
201#[cfg(feature = "std")]
202impl<I, E> Recover<E> for LocatingSlice<I>
203where
204 I: Recover<E>,
205 I: Stream,
206{
207 #[inline(always)]
208 fn record_err(
209 &mut self,
210 _token_start: &Self::Checkpoint,
211 _err_start: &Self::Checkpoint,
212 err: E,
213 ) -> Result<(), E> {
214 Err(err)
215 }
216
217 #[inline(always)]
219 fn is_recovery_supported() -> bool {
220 false
221 }
222}
223
224impl<I> StreamIsPartial for LocatingSlice<I>
225where
226 I: StreamIsPartial,
227{
228 type PartialState = I::PartialState;
229
230 #[inline]
231 fn complete(&mut self) -> Self::PartialState {
232 self.input.complete()
233 }
234
235 #[inline]
236 fn restore_partial(&mut self, state: Self::PartialState) {
237 self.input.restore_partial(state);
238 }
239
240 #[inline(always)]
241 fn is_partial_supported() -> bool {
242 I::is_partial_supported()
243 }
244
245 #[inline(always)]
246 fn is_partial(&self) -> bool {
247 self.input.is_partial()
248 }
249}
250
251impl<I> Offset for LocatingSlice<I>
252where
253 I: Stream,
254{
255 #[inline(always)]
256 fn offset_from(&self, other: &Self) -> usize {
257 self.offset_from(&other.checkpoint())
258 }
259}
260
261impl<I> Offset<<LocatingSlice<I> as Stream>::Checkpoint> for LocatingSlice<I>
262where
263 I: Stream,
264{
265 #[inline(always)]
266 fn offset_from(&self, other: &<LocatingSlice<I> as Stream>::Checkpoint) -> usize {
267 self.checkpoint().offset_from(other)
268 }
269}
270
271impl<I> AsBytes for LocatingSlice<I>
272where
273 I: AsBytes,
274{
275 #[inline(always)]
276 fn as_bytes(&self) -> &[u8] {
277 self.input.as_bytes()
278 }
279}
280
281impl<I> AsBStr for LocatingSlice<I>
282where
283 I: AsBStr,
284{
285 #[inline(always)]
286 fn as_bstr(&self) -> &[u8] {
287 self.input.as_bstr()
288 }
289}
290
291impl<I, U> Compare<U> for LocatingSlice<I>
292where
293 I: Compare<U>,
294{
295 #[inline(always)]
296 fn compare(&self, other: U) -> CompareResult {
297 self.input.compare(other)
298 }
299}
300
301impl<I, T> FindSlice<T> for LocatingSlice<I>
302where
303 I: FindSlice<T>,
304{
305 #[inline(always)]
306 fn find_slice(&self, substr: T) -> Option<core::ops::Range<usize>> {
307 self.input.find_slice(substr)
308 }
309}
310
311impl<I> UpdateSlice for LocatingSlice<I>
312where
313 I: UpdateSlice,
314{
315 #[inline(always)]
316 fn update_slice(mut self, inner: Self::Slice) -> Self {
317 self.input = I::update_slice(self.input, inner);
318 self
319 }
320}