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