winnow/stream/
partial.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(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
84pub struct Partial<I> {
85 input: I,
86 partial: bool,
87}
88
89impl<I> Partial<I>
90where
91 I: StreamIsPartial,
92{
93 #[inline]
95 pub fn new(input: I) -> Self {
96 debug_assert!(
97 !I::is_partial_supported(),
98 "`Partial` can only wrap complete sources"
99 );
100 let partial = true;
101 Self { input, partial }
102 }
103
104 #[inline(always)]
106 pub fn into_inner(self) -> I {
107 self.input
108 }
109}
110
111impl<I> Default for Partial<I>
112where
113 I: Default + StreamIsPartial,
114{
115 #[inline]
116 fn default() -> Self {
117 Self::new(I::default())
118 }
119}
120
121impl<I> crate::lib::std::ops::Deref for Partial<I> {
122 type Target = I;
123
124 #[inline(always)]
125 fn deref(&self) -> &Self::Target {
126 &self.input
127 }
128}
129
130impl<I: crate::lib::std::fmt::Display> crate::lib::std::fmt::Display for Partial<I> {
131 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
132 self.input.fmt(f)
133 }
134}
135
136impl<I> SliceLen for Partial<I>
137where
138 I: SliceLen,
139{
140 #[inline(always)]
141 fn slice_len(&self) -> usize {
142 self.input.slice_len()
143 }
144}
145
146impl<I: Stream> Stream for Partial<I> {
147 type Token = <I as Stream>::Token;
148 type Slice = <I as Stream>::Slice;
149
150 type IterOffsets = <I as Stream>::IterOffsets;
151
152 type Checkpoint = Checkpoint<I::Checkpoint, Self>;
153
154 #[inline(always)]
155 fn iter_offsets(&self) -> Self::IterOffsets {
156 self.input.iter_offsets()
157 }
158 #[inline(always)]
159 fn eof_offset(&self) -> usize {
160 self.input.eof_offset()
161 }
162
163 #[inline(always)]
164 fn next_token(&mut self) -> Option<Self::Token> {
165 self.input.next_token()
166 }
167
168 #[inline(always)]
169 fn peek_token(&self) -> Option<Self::Token> {
170 self.input.peek_token()
171 }
172
173 #[inline(always)]
174 fn offset_for<P>(&self, predicate: P) -> Option<usize>
175 where
176 P: Fn(Self::Token) -> bool,
177 {
178 self.input.offset_for(predicate)
179 }
180 #[inline(always)]
181 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
182 self.input.offset_at(tokens)
183 }
184 #[inline(always)]
185 fn next_slice(&mut self, offset: usize) -> Self::Slice {
186 self.input.next_slice(offset)
187 }
188 #[inline(always)]
189 unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
190 unsafe { self.input.next_slice_unchecked(offset) }
192 }
193 #[inline(always)]
194 fn peek_slice(&self, offset: usize) -> Self::Slice {
195 self.input.peek_slice(offset)
196 }
197 #[inline(always)]
198 unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
199 unsafe { self.input.peek_slice_unchecked(offset) }
201 }
202
203 #[inline(always)]
204 fn checkpoint(&self) -> Self::Checkpoint {
205 Checkpoint::<_, Self>::new(self.input.checkpoint())
206 }
207 #[inline(always)]
208 fn reset(&mut self, checkpoint: &Self::Checkpoint) {
209 self.input.reset(&checkpoint.inner);
210 }
211
212 #[inline(always)]
213 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
214 &self.input
215 }
216}
217
218impl<I> Location for Partial<I>
219where
220 I: Location,
221{
222 #[inline(always)]
223 fn previous_token_end(&self) -> usize {
224 self.input.previous_token_end()
225 }
226 #[inline(always)]
227 fn current_token_start(&self) -> usize {
228 self.input.current_token_start()
229 }
230}
231
232#[cfg(feature = "unstable-recover")]
233#[cfg(feature = "std")]
234impl<I, E> Recover<E> for Partial<I>
235where
236 I: Recover<E>,
237 I: Stream,
238{
239 #[inline(always)]
240 fn record_err(
241 &mut self,
242 _token_start: &Self::Checkpoint,
243 _err_start: &Self::Checkpoint,
244 err: E,
245 ) -> Result<(), E> {
246 Err(err)
247 }
248
249 #[inline(always)]
251 fn is_recovery_supported() -> bool {
252 false
253 }
254}
255
256impl<I> StreamIsPartial for Partial<I>
257where
258 I: StreamIsPartial,
259{
260 type PartialState = bool;
261
262 #[inline]
263 fn complete(&mut self) -> Self::PartialState {
264 core::mem::replace(&mut self.partial, false)
265 }
266
267 #[inline]
268 fn restore_partial(&mut self, state: Self::PartialState) {
269 self.partial = state;
270 }
271
272 #[inline(always)]
273 fn is_partial_supported() -> bool {
274 true
275 }
276
277 #[inline(always)]
278 fn is_partial(&self) -> bool {
279 self.partial
280 }
281}
282
283impl<I> Offset for Partial<I>
284where
285 I: Stream,
286{
287 #[inline(always)]
288 fn offset_from(&self, start: &Self) -> usize {
289 self.offset_from(&start.checkpoint())
290 }
291}
292
293impl<I> Offset<<Partial<I> as Stream>::Checkpoint> for Partial<I>
294where
295 I: Stream,
296{
297 #[inline(always)]
298 fn offset_from(&self, other: &<Partial<I> as Stream>::Checkpoint) -> usize {
299 self.checkpoint().offset_from(other)
300 }
301}
302
303impl<I> AsBytes for Partial<I>
304where
305 I: AsBytes,
306{
307 #[inline(always)]
308 fn as_bytes(&self) -> &[u8] {
309 self.input.as_bytes()
310 }
311}
312
313impl<I> AsBStr for Partial<I>
314where
315 I: AsBStr,
316{
317 #[inline(always)]
318 fn as_bstr(&self) -> &[u8] {
319 self.input.as_bstr()
320 }
321}
322
323impl<I, T> Compare<T> for Partial<I>
324where
325 I: Compare<T>,
326{
327 #[inline(always)]
328 fn compare(&self, t: T) -> CompareResult {
329 self.input.compare(t)
330 }
331}
332
333impl<I, T> FindSlice<T> for Partial<I>
334where
335 I: FindSlice<T>,
336{
337 #[inline(always)]
338 fn find_slice(&self, substr: T) -> Option<crate::lib::std::ops::Range<usize>> {
339 self.input.find_slice(substr)
340 }
341}
342
343impl<I> UpdateSlice for Partial<I>
344where
345 I: UpdateSlice,
346{
347 #[inline(always)]
348 fn update_slice(self, inner: Self::Slice) -> Self {
349 Partial {
350 input: I::update_slice(self.input, inner),
351 partial: self.partial,
352 }
353 }
354}