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