1 | //! Stream capability for combinators to parse |
2 | //! |
3 | //! Stream types include: |
4 | //! - `&[u8]` and [`Bytes`] for binary data |
5 | //! - `&str` (aliased as [`Str`]) and [`BStr`] for UTF-8 data |
6 | //! - [`Located`] can track the location within the original buffer to report |
7 | //! [spans][crate::Parser::with_span] |
8 | //! - [`Stateful`] to thread global state through your parsers |
9 | //! - [`Partial`] can mark an input as partial buffer that is being streamed into |
10 | //! - [Custom stream types][crate::_topic::stream] |
11 | |
12 | use core::num::NonZeroUsize; |
13 | |
14 | use crate::error::{ErrMode, ErrorKind, Needed, ParseError}; |
15 | use crate::lib::std::iter::{Cloned, Enumerate}; |
16 | use crate::lib::std::slice::Iter; |
17 | use crate::lib::std::str::from_utf8; |
18 | use crate::lib::std::str::CharIndices; |
19 | use crate::lib::std::str::FromStr; |
20 | use crate::IResult; |
21 | |
22 | #[cfg (feature = "alloc" )] |
23 | use crate::lib::std::collections::BTreeMap; |
24 | #[cfg (feature = "std" )] |
25 | use crate::lib::std::collections::HashMap; |
26 | #[cfg (feature = "alloc" )] |
27 | use crate::lib::std::string::String; |
28 | #[cfg (feature = "alloc" )] |
29 | use crate::lib::std::vec::Vec; |
30 | |
31 | mod impls; |
32 | #[cfg (test)] |
33 | mod tests; |
34 | |
35 | /// UTF-8 Stream |
36 | pub type Str<'i> = &'i str; |
37 | |
38 | /// Improved `Debug` experience for `&[u8]` byte streams |
39 | #[allow (clippy::derive_hash_xor_eq)] |
40 | #[derive (Hash)] |
41 | #[repr (transparent)] |
42 | pub struct Bytes([u8]); |
43 | |
44 | impl Bytes { |
45 | /// Make a stream out of a byte slice-like. |
46 | #[inline ] |
47 | pub fn new<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &Self { |
48 | Self::from_bytes(slice:bytes.as_ref()) |
49 | } |
50 | |
51 | #[inline ] |
52 | fn from_bytes(slice: &[u8]) -> &Self { |
53 | unsafe { crate::lib::std::mem::transmute(src:slice) } |
54 | } |
55 | |
56 | #[inline ] |
57 | fn as_bytes(&self) -> &[u8] { |
58 | &self.0 |
59 | } |
60 | } |
61 | |
62 | /// Improved `Debug` experience for `&[u8]` UTF-8-ish streams |
63 | #[allow (clippy::derive_hash_xor_eq)] |
64 | #[derive (Hash)] |
65 | #[repr (transparent)] |
66 | pub struct BStr([u8]); |
67 | |
68 | impl BStr { |
69 | /// Make a stream out of a byte slice-like. |
70 | #[inline ] |
71 | pub fn new<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &Self { |
72 | Self::from_bytes(slice:bytes.as_ref()) |
73 | } |
74 | |
75 | #[inline ] |
76 | fn from_bytes(slice: &[u8]) -> &Self { |
77 | unsafe { crate::lib::std::mem::transmute(src:slice) } |
78 | } |
79 | |
80 | #[inline ] |
81 | fn as_bytes(&self) -> &[u8] { |
82 | &self.0 |
83 | } |
84 | } |
85 | |
86 | /// Allow collecting the span of a parsed token |
87 | /// |
88 | /// See [`Parser::span`][crate::Parser::span] and [`Parser::with_span`][crate::Parser::with_span] for more details |
89 | #[derive (Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)] |
90 | pub struct Located<I> { |
91 | initial: I, |
92 | input: I, |
93 | } |
94 | |
95 | impl<I> Located<I> |
96 | where |
97 | I: Clone + Offset, |
98 | { |
99 | /// Wrap another Stream with span tracking |
100 | pub fn new(input: I) -> Self { |
101 | let initial: I = input.clone(); |
102 | Self { initial, input } |
103 | } |
104 | |
105 | fn location(&self) -> usize { |
106 | self.initial.offset_to(&self.input) |
107 | } |
108 | } |
109 | |
110 | impl<I> AsRef<I> for Located<I> { |
111 | #[inline (always)] |
112 | fn as_ref(&self) -> &I { |
113 | &self.input |
114 | } |
115 | } |
116 | |
117 | impl<I> crate::lib::std::ops::Deref for Located<I> { |
118 | type Target = I; |
119 | |
120 | #[inline (always)] |
121 | fn deref(&self) -> &Self::Target { |
122 | &self.input |
123 | } |
124 | } |
125 | |
126 | impl<I: crate::lib::std::fmt::Display> crate::lib::std::fmt::Display for Located<I> { |
127 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
128 | self.input.fmt(f) |
129 | } |
130 | } |
131 | |
132 | /// Thread global state through your parsers |
133 | /// |
134 | /// Use cases |
135 | /// - Recursion checks |
136 | /// - Error recovery |
137 | /// - Debugging |
138 | /// |
139 | /// # Example |
140 | /// |
141 | /// ``` |
142 | /// # use std::cell::Cell; |
143 | /// # use winnow::prelude::*; |
144 | /// # use winnow::stream::Stateful; |
145 | /// # use winnow::ascii::alpha1; |
146 | /// # type Error = (); |
147 | /// |
148 | /// #[derive(Clone, Debug)] |
149 | /// struct State<'s>(&'s Cell<u32>); |
150 | /// |
151 | /// impl<'s> State<'s> { |
152 | /// fn count(&self) { |
153 | /// self.0.set(self.0.get() + 1); |
154 | /// } |
155 | /// } |
156 | /// |
157 | /// type Stream<'is> = Stateful<&'is str, State<'is>>; |
158 | /// |
159 | /// fn word(i: Stream<'_>) -> IResult<Stream<'_>, &str> { |
160 | /// i.state.count(); |
161 | /// alpha1(i) |
162 | /// } |
163 | /// |
164 | /// let data = "Hello" ; |
165 | /// let state = Cell::new(0); |
166 | /// let input = Stream { input: data, state: State(&state) }; |
167 | /// let output = word.parse(input).unwrap(); |
168 | /// assert_eq!(state.get(), 1); |
169 | /// ``` |
170 | #[derive (Clone, Copy, Debug, Eq, PartialEq)] |
171 | pub struct Stateful<I, S> { |
172 | /// Inner input being wrapped in state |
173 | pub input: I, |
174 | /// User-provided state |
175 | pub state: S, |
176 | } |
177 | |
178 | impl<I, S> AsRef<I> for Stateful<I, S> { |
179 | #[inline (always)] |
180 | fn as_ref(&self) -> &I { |
181 | &self.input |
182 | } |
183 | } |
184 | |
185 | impl<I, S> crate::lib::std::ops::Deref for Stateful<I, S> { |
186 | type Target = I; |
187 | |
188 | #[inline (always)] |
189 | fn deref(&self) -> &Self::Target { |
190 | self.as_ref() |
191 | } |
192 | } |
193 | |
194 | impl<I: crate::lib::std::fmt::Display, S> crate::lib::std::fmt::Display for Stateful<I, S> { |
195 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
196 | self.input.fmt(f) |
197 | } |
198 | } |
199 | |
200 | /// Mark the input as a partial buffer for streaming input. |
201 | /// |
202 | /// Complete input means that we already have all of the data. This will be the common case with |
203 | /// small files that can be read entirely to memory. |
204 | /// |
205 | /// In contrast, streaming input assumes that we might not have all of the data. |
206 | /// This can happen with some network protocol or large file parsers, where the |
207 | /// input buffer can be full and need to be resized or refilled. |
208 | /// - [`ErrMode::Incomplete`] will report how much more data is needed. |
209 | /// - [`Parser::complete_err`][crate::Parser::complete_err] transform [`ErrMode::Incomplete`] to |
210 | /// [`ErrMode::Backtrack`] |
211 | /// |
212 | /// See also [`StreamIsPartial`] to tell whether the input supports complete or partial parsing. |
213 | /// |
214 | /// See also [Special Topics: Parsing Partial Input][crate::_topic::partial]. |
215 | /// |
216 | /// # Example |
217 | /// |
218 | /// Here is how it works in practice: |
219 | /// |
220 | /// ```rust |
221 | /// # use winnow::{IResult, error::ErrMode, error::Needed, error::{Error, ErrorKind}, token, ascii, stream::Partial}; |
222 | /// # use winnow::prelude::*; |
223 | /// |
224 | /// fn take_partial(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { |
225 | /// token::take(4u8).parse_next(i) |
226 | /// } |
227 | /// |
228 | /// fn take_complete(i: &[u8]) -> IResult<&[u8], &[u8]> { |
229 | /// token::take(4u8).parse_next(i) |
230 | /// } |
231 | /// |
232 | /// // both parsers will take 4 bytes as expected |
233 | /// assert_eq!(take_partial(Partial::new(&b"abcde" [..])), Ok((Partial::new(&b"e" [..]), &b"abcd" [..]))); |
234 | /// assert_eq!(take_complete(&b"abcde" [..]), Ok((&b"e" [..], &b"abcd" [..]))); |
235 | /// |
236 | /// // if the input is smaller than 4 bytes, the partial parser |
237 | /// // will return `Incomplete` to indicate that we need more data |
238 | /// assert_eq!(take_partial(Partial::new(&b"abc" [..])), Err(ErrMode::Incomplete(Needed::new(1)))); |
239 | /// |
240 | /// // but the complete parser will return an error |
241 | /// assert_eq!(take_complete(&b"abc" [..]), Err(ErrMode::Backtrack(Error::new(&b"abc" [..], ErrorKind::Slice)))); |
242 | /// |
243 | /// // the alpha0 function recognizes 0 or more alphabetic characters |
244 | /// fn alpha0_partial(i: Partial<&str>) -> IResult<Partial<&str>, &str> { |
245 | /// ascii::alpha0(i) |
246 | /// } |
247 | /// |
248 | /// fn alpha0_complete(i: &str) -> IResult<&str, &str> { |
249 | /// ascii::alpha0(i) |
250 | /// } |
251 | /// |
252 | /// // if there's a clear limit to the recognized characters, both parsers work the same way |
253 | /// assert_eq!(alpha0_partial(Partial::new("abcd;" )), Ok((Partial::new(";" ), "abcd" ))); |
254 | /// assert_eq!(alpha0_complete("abcd;" ), Ok((";" , "abcd" ))); |
255 | /// |
256 | /// // but when there's no limit, the partial version returns `Incomplete`, because it cannot |
257 | /// // know if more input data should be recognized. The whole input could be "abcd;", or |
258 | /// // "abcde;" |
259 | /// assert_eq!(alpha0_partial(Partial::new("abcd" )), Err(ErrMode::Incomplete(Needed::new(1)))); |
260 | /// |
261 | /// // while the complete version knows that all of the data is there |
262 | /// assert_eq!(alpha0_complete("abcd" ), Ok(("" , "abcd" ))); |
263 | /// ``` |
264 | #[derive (Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] |
265 | pub struct Partial<I> { |
266 | input: I, |
267 | partial: bool, |
268 | } |
269 | |
270 | impl<I> Partial<I> |
271 | where |
272 | I: StreamIsPartial, |
273 | { |
274 | /// Create a partial input |
275 | pub fn new(input: I) -> Self { |
276 | debug_assert!( |
277 | !I::is_partial_supported(), |
278 | "`Partial` can only wrap complete sources" |
279 | ); |
280 | let partial: bool = true; |
281 | Self { input, partial } |
282 | } |
283 | |
284 | /// Extract the original [`Stream`] |
285 | #[inline (always)] |
286 | pub fn into_inner(self) -> I { |
287 | self.input |
288 | } |
289 | } |
290 | |
291 | impl<I> Default for Partial<I> |
292 | where |
293 | I: Default + StreamIsPartial, |
294 | { |
295 | fn default() -> Self { |
296 | Self::new(I::default()) |
297 | } |
298 | } |
299 | |
300 | impl<I> crate::lib::std::ops::Deref for Partial<I> { |
301 | type Target = I; |
302 | |
303 | #[inline (always)] |
304 | fn deref(&self) -> &Self::Target { |
305 | &self.input |
306 | } |
307 | } |
308 | |
309 | impl<I: crate::lib::std::fmt::Display> crate::lib::std::fmt::Display for Partial<I> { |
310 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
311 | self.input.fmt(f) |
312 | } |
313 | } |
314 | |
315 | /// Abstract method to calculate the input length |
316 | pub trait SliceLen { |
317 | /// Calculates the input length, as indicated by its name, |
318 | /// and the name of the trait itself |
319 | fn slice_len(&self) -> usize; |
320 | } |
321 | |
322 | impl<'a, T> SliceLen for &'a [T] { |
323 | #[inline ] |
324 | fn slice_len(&self) -> usize { |
325 | self.len() |
326 | } |
327 | } |
328 | |
329 | impl<T, const LEN: usize> SliceLen for [T; LEN] { |
330 | #[inline ] |
331 | fn slice_len(&self) -> usize { |
332 | self.len() |
333 | } |
334 | } |
335 | |
336 | impl<'a, T, const LEN: usize> SliceLen for &'a [T; LEN] { |
337 | #[inline ] |
338 | fn slice_len(&self) -> usize { |
339 | self.len() |
340 | } |
341 | } |
342 | |
343 | impl<'a> SliceLen for &'a str { |
344 | #[inline ] |
345 | fn slice_len(&self) -> usize { |
346 | self.len() |
347 | } |
348 | } |
349 | |
350 | impl<'a> SliceLen for &'a Bytes { |
351 | #[inline ] |
352 | fn slice_len(&self) -> usize { |
353 | self.len() |
354 | } |
355 | } |
356 | |
357 | impl<'a> SliceLen for &'a BStr { |
358 | #[inline ] |
359 | fn slice_len(&self) -> usize { |
360 | self.len() |
361 | } |
362 | } |
363 | |
364 | impl<I> SliceLen for (I, usize, usize) |
365 | where |
366 | I: SliceLen, |
367 | { |
368 | #[inline (always)] |
369 | fn slice_len(&self) -> usize { |
370 | self.0.slice_len() * 8 + self.2 - self.1 |
371 | } |
372 | } |
373 | |
374 | impl<I> SliceLen for Located<I> |
375 | where |
376 | I: SliceLen, |
377 | { |
378 | #[inline (always)] |
379 | fn slice_len(&self) -> usize { |
380 | self.input.slice_len() |
381 | } |
382 | } |
383 | |
384 | impl<I, S> SliceLen for Stateful<I, S> |
385 | where |
386 | I: SliceLen, |
387 | { |
388 | #[inline (always)] |
389 | fn slice_len(&self) -> usize { |
390 | self.input.slice_len() |
391 | } |
392 | } |
393 | |
394 | impl<I> SliceLen for Partial<I> |
395 | where |
396 | I: SliceLen, |
397 | { |
398 | #[inline (always)] |
399 | fn slice_len(&self) -> usize { |
400 | self.input.slice_len() |
401 | } |
402 | } |
403 | |
404 | /// Core definition for parser input state |
405 | pub trait Stream: Offset + Clone + crate::lib::std::fmt::Debug { |
406 | /// The smallest unit being parsed |
407 | /// |
408 | /// Example: `u8` for `&[u8]` or `char` for `&str` |
409 | type Token: crate::lib::std::fmt::Debug; |
410 | /// Sequence of `Token`s |
411 | /// |
412 | /// Example: `&[u8]` for `Located<&[u8]>` or `&str` for `Located<&str>` |
413 | type Slice: crate::lib::std::fmt::Debug; |
414 | |
415 | /// Iterate with the offset from the current location |
416 | type IterOffsets: Iterator<Item = (usize, Self::Token)>; |
417 | |
418 | /// Iterate with the offset from the current location |
419 | fn iter_offsets(&self) -> Self::IterOffsets; |
420 | /// Returns the offaet to the end of the input |
421 | fn eof_offset(&self) -> usize; |
422 | |
423 | /// Split off the next token from the input |
424 | fn next_token(&self) -> Option<(Self, Self::Token)>; |
425 | |
426 | /// Finds the offset of the next matching token |
427 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
428 | where |
429 | P: Fn(Self::Token) -> bool; |
430 | /// Get the offset for the number of `tokens` into the stream |
431 | /// |
432 | /// This means "0 tokens" will return `0` offset |
433 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed>; |
434 | /// Split off a slice of tokens from the input |
435 | /// |
436 | /// **NOTE:** For inputs with variable width tokens, like `&str`'s `char`, `offset` might not correspond |
437 | /// with the number of tokens. To get a valid offset, use: |
438 | /// - [`Stream::eof_offset`] |
439 | /// - [`Stream::iter_offsets`] |
440 | /// - [`Stream::offset_for`] |
441 | /// - [`Stream::offset_at`] |
442 | /// |
443 | /// # Panic |
444 | /// |
445 | /// This will panic if |
446 | /// |
447 | /// * Indexes must be within bounds of the original input; |
448 | /// * Indexes must uphold invariants of the stream, like for `str` they must lie on UTF-8 |
449 | /// sequence boundaries. |
450 | /// |
451 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice); |
452 | } |
453 | |
454 | impl<'i, T> Stream for &'i [T] |
455 | where |
456 | T: Clone + crate::lib::std::fmt::Debug, |
457 | { |
458 | type Token = T; |
459 | type Slice = &'i [T]; |
460 | |
461 | type IterOffsets = Enumerate<Cloned<Iter<'i, T>>>; |
462 | |
463 | #[inline (always)] |
464 | fn iter_offsets(&self) -> Self::IterOffsets { |
465 | self.iter().cloned().enumerate() |
466 | } |
467 | #[inline (always)] |
468 | fn eof_offset(&self) -> usize { |
469 | self.len() |
470 | } |
471 | |
472 | #[inline (always)] |
473 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
474 | self.split_first() |
475 | .map(|(token, next)| (next, token.clone())) |
476 | } |
477 | |
478 | #[inline (always)] |
479 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
480 | where |
481 | P: Fn(Self::Token) -> bool, |
482 | { |
483 | self.iter().position(|b| predicate(b.clone())) |
484 | } |
485 | #[inline (always)] |
486 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
487 | if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) { |
488 | Err(Needed::Size(needed)) |
489 | } else { |
490 | Ok(tokens) |
491 | } |
492 | } |
493 | #[inline (always)] |
494 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
495 | let (slice, next) = self.split_at(offset); |
496 | (next, slice) |
497 | } |
498 | } |
499 | |
500 | impl<'i> Stream for &'i str { |
501 | type Token = char; |
502 | type Slice = &'i str; |
503 | |
504 | type IterOffsets = CharIndices<'i>; |
505 | |
506 | #[inline (always)] |
507 | fn iter_offsets(&self) -> Self::IterOffsets { |
508 | self.char_indices() |
509 | } |
510 | #[inline (always)] |
511 | fn eof_offset(&self) -> usize { |
512 | self.len() |
513 | } |
514 | |
515 | #[inline (always)] |
516 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
517 | let c = self.chars().next()?; |
518 | let offset = c.len(); |
519 | Some((&self[offset..], c)) |
520 | } |
521 | |
522 | #[inline (always)] |
523 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
524 | where |
525 | P: Fn(Self::Token) -> bool, |
526 | { |
527 | for (o, c) in self.iter_offsets() { |
528 | if predicate(c) { |
529 | return Some(o); |
530 | } |
531 | } |
532 | None |
533 | } |
534 | #[inline ] |
535 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
536 | let mut cnt = 0; |
537 | for (offset, _) in self.iter_offsets() { |
538 | if cnt == tokens { |
539 | return Ok(offset); |
540 | } |
541 | cnt += 1; |
542 | } |
543 | |
544 | if cnt == tokens { |
545 | Ok(self.eof_offset()) |
546 | } else { |
547 | Err(Needed::Unknown) |
548 | } |
549 | } |
550 | #[inline (always)] |
551 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
552 | let (slice, next) = self.split_at(offset); |
553 | (next, slice) |
554 | } |
555 | } |
556 | |
557 | impl<'i> Stream for &'i Bytes { |
558 | type Token = u8; |
559 | type Slice = &'i [u8]; |
560 | |
561 | type IterOffsets = Enumerate<Cloned<Iter<'i, u8>>>; |
562 | |
563 | #[inline (always)] |
564 | fn iter_offsets(&self) -> Self::IterOffsets { |
565 | self.iter().cloned().enumerate() |
566 | } |
567 | #[inline (always)] |
568 | fn eof_offset(&self) -> usize { |
569 | self.len() |
570 | } |
571 | |
572 | #[inline (always)] |
573 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
574 | if self.is_empty() { |
575 | None |
576 | } else { |
577 | Some((Bytes::from_bytes(&self[1..]), self[0])) |
578 | } |
579 | } |
580 | |
581 | #[inline (always)] |
582 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
583 | where |
584 | P: Fn(Self::Token) -> bool, |
585 | { |
586 | self.iter().position(|b| predicate(*b)) |
587 | } |
588 | #[inline (always)] |
589 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
590 | if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) { |
591 | Err(Needed::Size(needed)) |
592 | } else { |
593 | Ok(tokens) |
594 | } |
595 | } |
596 | #[inline (always)] |
597 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
598 | let (next, slice) = (&self.0).next_slice(offset); |
599 | (Bytes::from_bytes(next), slice) |
600 | } |
601 | } |
602 | |
603 | impl<'i> Stream for &'i BStr { |
604 | type Token = u8; |
605 | type Slice = &'i [u8]; |
606 | |
607 | type IterOffsets = Enumerate<Cloned<Iter<'i, u8>>>; |
608 | |
609 | #[inline (always)] |
610 | fn iter_offsets(&self) -> Self::IterOffsets { |
611 | self.iter().cloned().enumerate() |
612 | } |
613 | #[inline (always)] |
614 | fn eof_offset(&self) -> usize { |
615 | self.len() |
616 | } |
617 | |
618 | #[inline (always)] |
619 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
620 | if self.is_empty() { |
621 | None |
622 | } else { |
623 | Some((BStr::from_bytes(&self[1..]), self[0])) |
624 | } |
625 | } |
626 | |
627 | #[inline (always)] |
628 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
629 | where |
630 | P: Fn(Self::Token) -> bool, |
631 | { |
632 | self.iter().position(|b| predicate(*b)) |
633 | } |
634 | #[inline (always)] |
635 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
636 | if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) { |
637 | Err(Needed::Size(needed)) |
638 | } else { |
639 | Ok(tokens) |
640 | } |
641 | } |
642 | #[inline (always)] |
643 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
644 | let (next, slice) = (&self.0).next_slice(offset); |
645 | (BStr::from_bytes(next), slice) |
646 | } |
647 | } |
648 | |
649 | impl<I> Stream for (I, usize) |
650 | where |
651 | I: Stream<Token = u8>, |
652 | { |
653 | type Token = bool; |
654 | type Slice = (I::Slice, usize, usize); |
655 | |
656 | type IterOffsets = BitOffsets<I>; |
657 | |
658 | #[inline (always)] |
659 | fn iter_offsets(&self) -> Self::IterOffsets { |
660 | BitOffsets { |
661 | i: self.clone(), |
662 | o: 0, |
663 | } |
664 | } |
665 | #[inline (always)] |
666 | fn eof_offset(&self) -> usize { |
667 | let offset = self.0.eof_offset() * 8; |
668 | if offset == 0 { |
669 | 0 |
670 | } else { |
671 | offset - self.1 |
672 | } |
673 | } |
674 | |
675 | #[inline (always)] |
676 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
677 | next_bit(self) |
678 | } |
679 | |
680 | #[inline (always)] |
681 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
682 | where |
683 | P: Fn(Self::Token) -> bool, |
684 | { |
685 | self.iter_offsets() |
686 | .find_map(|(o, b)| predicate(b).then(|| o)) |
687 | } |
688 | #[inline (always)] |
689 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
690 | if let Some(needed) = tokens |
691 | .checked_sub(self.eof_offset()) |
692 | .and_then(NonZeroUsize::new) |
693 | { |
694 | Err(Needed::Size(needed)) |
695 | } else { |
696 | Ok(tokens) |
697 | } |
698 | } |
699 | #[inline (always)] |
700 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
701 | let byte_offset = (offset + self.1) / 8; |
702 | let end_offset = (offset + self.1) % 8; |
703 | let (i, s) = self.0.next_slice(byte_offset); |
704 | ((i, end_offset), (s, self.1, end_offset)) |
705 | } |
706 | } |
707 | |
708 | /// Iterator for [bit][crate::binary::bits] stream (`(I, usize)`) |
709 | pub struct BitOffsets<I> { |
710 | i: (I, usize), |
711 | o: usize, |
712 | } |
713 | |
714 | impl<I> Iterator for BitOffsets<I> |
715 | where |
716 | I: Stream<Token = u8>, |
717 | { |
718 | type Item = (usize, bool); |
719 | fn next(&mut self) -> Option<Self::Item> { |
720 | let (next: (I, usize), b: bool) = next_bit(&self.i)?; |
721 | let o: usize = self.o; |
722 | |
723 | self.i = next; |
724 | self.o += 1; |
725 | |
726 | Some((o, b)) |
727 | } |
728 | } |
729 | |
730 | fn next_bit<I>(i: &(I, usize)) -> Option<((I, usize), bool)> |
731 | where |
732 | I: Stream<Token = u8>, |
733 | { |
734 | if i.eof_offset() == 0 { |
735 | return None; |
736 | } |
737 | |
738 | let i: (I, usize) = i.clone(); |
739 | let (next_i: I, byte: u8) = i.0.next_token()?; |
740 | let bit: bool = (byte >> i.1) & 0x1 == 0x1; |
741 | |
742 | let next_offset: usize = i.1 + 1; |
743 | if next_offset == 8 { |
744 | Some(((next_i, 0), bit)) |
745 | } else { |
746 | Some(((i.0, next_offset), bit)) |
747 | } |
748 | } |
749 | |
750 | impl<I: Stream> Stream for Located<I> { |
751 | type Token = <I as Stream>::Token; |
752 | type Slice = <I as Stream>::Slice; |
753 | |
754 | type IterOffsets = <I as Stream>::IterOffsets; |
755 | |
756 | #[inline (always)] |
757 | fn iter_offsets(&self) -> Self::IterOffsets { |
758 | self.input.iter_offsets() |
759 | } |
760 | #[inline (always)] |
761 | fn eof_offset(&self) -> usize { |
762 | self.input.eof_offset() |
763 | } |
764 | |
765 | #[inline (always)] |
766 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
767 | let (next, token) = self.input.next_token()?; |
768 | Some(( |
769 | Self { |
770 | initial: self.initial.clone(), |
771 | input: next, |
772 | }, |
773 | token, |
774 | )) |
775 | } |
776 | |
777 | #[inline (always)] |
778 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
779 | where |
780 | P: Fn(Self::Token) -> bool, |
781 | { |
782 | self.input.offset_for(predicate) |
783 | } |
784 | #[inline (always)] |
785 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
786 | self.input.offset_at(tokens) |
787 | } |
788 | #[inline (always)] |
789 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
790 | let (next, slice) = self.input.next_slice(offset); |
791 | ( |
792 | Self { |
793 | initial: self.initial.clone(), |
794 | input: next, |
795 | }, |
796 | slice, |
797 | ) |
798 | } |
799 | } |
800 | |
801 | impl<I: Stream, S: Clone + crate::lib::std::fmt::Debug> Stream for Stateful<I, S> { |
802 | type Token = <I as Stream>::Token; |
803 | type Slice = <I as Stream>::Slice; |
804 | |
805 | type IterOffsets = <I as Stream>::IterOffsets; |
806 | |
807 | #[inline (always)] |
808 | fn iter_offsets(&self) -> Self::IterOffsets { |
809 | self.input.iter_offsets() |
810 | } |
811 | #[inline (always)] |
812 | fn eof_offset(&self) -> usize { |
813 | self.input.eof_offset() |
814 | } |
815 | |
816 | #[inline (always)] |
817 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
818 | let (next, token) = self.input.next_token()?; |
819 | Some(( |
820 | Self { |
821 | input: next, |
822 | state: self.state.clone(), |
823 | }, |
824 | token, |
825 | )) |
826 | } |
827 | |
828 | #[inline (always)] |
829 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
830 | where |
831 | P: Fn(Self::Token) -> bool, |
832 | { |
833 | self.input.offset_for(predicate) |
834 | } |
835 | #[inline (always)] |
836 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
837 | self.input.offset_at(tokens) |
838 | } |
839 | #[inline (always)] |
840 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
841 | let (next, slice) = self.input.next_slice(offset); |
842 | ( |
843 | Self { |
844 | input: next, |
845 | state: self.state.clone(), |
846 | }, |
847 | slice, |
848 | ) |
849 | } |
850 | } |
851 | |
852 | impl<I: Stream> Stream for Partial<I> { |
853 | type Token = <I as Stream>::Token; |
854 | type Slice = <I as Stream>::Slice; |
855 | |
856 | type IterOffsets = <I as Stream>::IterOffsets; |
857 | |
858 | #[inline (always)] |
859 | fn iter_offsets(&self) -> Self::IterOffsets { |
860 | self.input.iter_offsets() |
861 | } |
862 | #[inline (always)] |
863 | fn eof_offset(&self) -> usize { |
864 | self.input.eof_offset() |
865 | } |
866 | |
867 | #[inline (always)] |
868 | fn next_token(&self) -> Option<(Self, Self::Token)> { |
869 | let (next, token) = self.input.next_token()?; |
870 | Some(( |
871 | Partial { |
872 | input: next, |
873 | partial: self.partial, |
874 | }, |
875 | token, |
876 | )) |
877 | } |
878 | |
879 | #[inline (always)] |
880 | fn offset_for<P>(&self, predicate: P) -> Option<usize> |
881 | where |
882 | P: Fn(Self::Token) -> bool, |
883 | { |
884 | self.input.offset_for(predicate) |
885 | } |
886 | #[inline (always)] |
887 | fn offset_at(&self, tokens: usize) -> Result<usize, Needed> { |
888 | self.input.offset_at(tokens) |
889 | } |
890 | #[inline (always)] |
891 | fn next_slice(&self, offset: usize) -> (Self, Self::Slice) { |
892 | let (next, slice) = self.input.next_slice(offset); |
893 | ( |
894 | Partial { |
895 | input: next, |
896 | partial: self.partial, |
897 | }, |
898 | slice, |
899 | ) |
900 | } |
901 | } |
902 | |
903 | /// Number of indices input has advanced since start of parsing |
904 | pub trait Location { |
905 | /// Number of indices input has advanced since start of parsing |
906 | fn location(&self) -> usize; |
907 | } |
908 | |
909 | impl<I> Location for Located<I> |
910 | where |
911 | I: Clone + Offset, |
912 | { |
913 | #[inline (always)] |
914 | fn location(&self) -> usize { |
915 | self.location() |
916 | } |
917 | } |
918 | |
919 | impl<I, S> Location for Stateful<I, S> |
920 | where |
921 | I: Location, |
922 | { |
923 | #[inline (always)] |
924 | fn location(&self) -> usize { |
925 | self.input.location() |
926 | } |
927 | } |
928 | |
929 | impl<I> Location for Partial<I> |
930 | where |
931 | I: Location, |
932 | { |
933 | #[inline (always)] |
934 | fn location(&self) -> usize { |
935 | self.input.location() |
936 | } |
937 | } |
938 | |
939 | /// Marks the input as being the complete buffer or a partial buffer for streaming input |
940 | /// |
941 | /// See [`Partial`] for marking a presumed complete buffer type as a streaming buffer. |
942 | pub trait StreamIsPartial: Sized { |
943 | /// Whether the stream is currently partial or complete |
944 | type PartialState; |
945 | |
946 | /// Mark the stream is complete |
947 | #[must_use ] |
948 | fn complete(&mut self) -> Self::PartialState; |
949 | |
950 | /// Restore the stream back to its previous state |
951 | fn restore_partial(&mut self, state: Self::PartialState); |
952 | |
953 | /// Report whether the [`Stream`] is can ever be incomplete |
954 | fn is_partial_supported() -> bool; |
955 | |
956 | /// Report whether the [`Stream`] is currently incomplete |
957 | #[inline (always)] |
958 | fn is_partial(&self) -> bool { |
959 | Self::is_partial_supported() |
960 | } |
961 | } |
962 | |
963 | impl<'a, T> StreamIsPartial for &'a [T] { |
964 | type PartialState = (); |
965 | |
966 | fn complete(&mut self) -> Self::PartialState {} |
967 | |
968 | fn restore_partial(&mut self, _state: Self::PartialState) {} |
969 | |
970 | #[inline (always)] |
971 | fn is_partial_supported() -> bool { |
972 | false |
973 | } |
974 | } |
975 | |
976 | impl<'a> StreamIsPartial for &'a str { |
977 | type PartialState = (); |
978 | |
979 | fn complete(&mut self) -> Self::PartialState { |
980 | // Already complete |
981 | } |
982 | |
983 | fn restore_partial(&mut self, _state: Self::PartialState) {} |
984 | |
985 | #[inline (always)] |
986 | fn is_partial_supported() -> bool { |
987 | false |
988 | } |
989 | } |
990 | |
991 | impl<'a> StreamIsPartial for &'a Bytes { |
992 | type PartialState = (); |
993 | |
994 | fn complete(&mut self) -> Self::PartialState { |
995 | // Already complete |
996 | } |
997 | |
998 | fn restore_partial(&mut self, _state: Self::PartialState) {} |
999 | |
1000 | #[inline (always)] |
1001 | fn is_partial_supported() -> bool { |
1002 | false |
1003 | } |
1004 | } |
1005 | |
1006 | impl<'a> StreamIsPartial for &'a BStr { |
1007 | type PartialState = (); |
1008 | |
1009 | fn complete(&mut self) -> Self::PartialState { |
1010 | // Already complete |
1011 | } |
1012 | |
1013 | fn restore_partial(&mut self, _state: Self::PartialState) {} |
1014 | |
1015 | #[inline (always)] |
1016 | fn is_partial_supported() -> bool { |
1017 | false |
1018 | } |
1019 | } |
1020 | |
1021 | impl<I> StreamIsPartial for (I, usize) |
1022 | where |
1023 | I: StreamIsPartial, |
1024 | { |
1025 | type PartialState = I::PartialState; |
1026 | |
1027 | fn complete(&mut self) -> Self::PartialState { |
1028 | self.0.complete() |
1029 | } |
1030 | |
1031 | fn restore_partial(&mut self, state: Self::PartialState) { |
1032 | self.0.restore_partial(state); |
1033 | } |
1034 | |
1035 | #[inline (always)] |
1036 | fn is_partial_supported() -> bool { |
1037 | I::is_partial_supported() |
1038 | } |
1039 | |
1040 | #[inline (always)] |
1041 | fn is_partial(&self) -> bool { |
1042 | self.0.is_partial() |
1043 | } |
1044 | } |
1045 | |
1046 | impl<I> StreamIsPartial for Located<I> |
1047 | where |
1048 | I: StreamIsPartial, |
1049 | { |
1050 | type PartialState = I::PartialState; |
1051 | |
1052 | fn complete(&mut self) -> Self::PartialState { |
1053 | self.input.complete() |
1054 | } |
1055 | |
1056 | fn restore_partial(&mut self, state: Self::PartialState) { |
1057 | self.input.restore_partial(state); |
1058 | } |
1059 | |
1060 | #[inline (always)] |
1061 | fn is_partial_supported() -> bool { |
1062 | I::is_partial_supported() |
1063 | } |
1064 | |
1065 | #[inline (always)] |
1066 | fn is_partial(&self) -> bool { |
1067 | self.input.is_partial() |
1068 | } |
1069 | } |
1070 | |
1071 | impl<I, S> StreamIsPartial for Stateful<I, S> |
1072 | where |
1073 | I: StreamIsPartial, |
1074 | { |
1075 | type PartialState = I::PartialState; |
1076 | |
1077 | fn complete(&mut self) -> Self::PartialState { |
1078 | self.input.complete() |
1079 | } |
1080 | |
1081 | fn restore_partial(&mut self, state: Self::PartialState) { |
1082 | self.input.restore_partial(state); |
1083 | } |
1084 | |
1085 | #[inline (always)] |
1086 | fn is_partial_supported() -> bool { |
1087 | I::is_partial_supported() |
1088 | } |
1089 | |
1090 | #[inline (always)] |
1091 | fn is_partial(&self) -> bool { |
1092 | self.input.is_partial() |
1093 | } |
1094 | } |
1095 | |
1096 | impl<I> StreamIsPartial for Partial<I> |
1097 | where |
1098 | I: StreamIsPartial, |
1099 | { |
1100 | type PartialState = bool; |
1101 | |
1102 | fn complete(&mut self) -> Self::PartialState { |
1103 | core::mem::replace(&mut self.partial, src:false) |
1104 | } |
1105 | |
1106 | fn restore_partial(&mut self, state: Self::PartialState) { |
1107 | self.partial = state; |
1108 | } |
1109 | |
1110 | #[inline (always)] |
1111 | fn is_partial_supported() -> bool { |
1112 | true |
1113 | } |
1114 | |
1115 | #[inline (always)] |
1116 | fn is_partial(&self) -> bool { |
1117 | self.partial |
1118 | } |
1119 | } |
1120 | |
1121 | /// Useful functions to calculate the offset between slices and show a hexdump of a slice |
1122 | pub trait Offset { |
1123 | /// Offset between the first byte of self and the first byte of the argument |
1124 | fn offset_to(&self, second: &Self) -> usize; |
1125 | } |
1126 | |
1127 | impl<'a, T> Offset for &'a [T] { |
1128 | #[inline (always)] |
1129 | fn offset_to(&self, second: &Self) -> usize { |
1130 | (*self).offset_to(*second) |
1131 | } |
1132 | } |
1133 | |
1134 | /// Convenience implementation to accept `&[T]` instead of `&&[T]` as above |
1135 | impl<T> Offset for [T] { |
1136 | #[inline ] |
1137 | fn offset_to(&self, second: &Self) -> usize { |
1138 | let fst: *const T = self.as_ptr(); |
1139 | let snd: *const T = second.as_ptr(); |
1140 | |
1141 | debug_assert!( |
1142 | fst <= snd, |
1143 | "`Offset::offset_to` only accepts slices of `self`" |
1144 | ); |
1145 | snd as usize - fst as usize |
1146 | } |
1147 | } |
1148 | |
1149 | impl<'a> Offset for &'a str { |
1150 | #[inline (always)] |
1151 | fn offset_to(&self, second: &Self) -> usize { |
1152 | self.as_bytes().offset_to(second:second.as_bytes()) |
1153 | } |
1154 | } |
1155 | |
1156 | /// Convenience implementation to accept `&str` instead of `&&str` as above |
1157 | impl Offset for str { |
1158 | #[inline (always)] |
1159 | fn offset_to(&self, second: &Self) -> usize { |
1160 | self.as_bytes().offset_to(second:second.as_bytes()) |
1161 | } |
1162 | } |
1163 | |
1164 | impl Offset for Bytes { |
1165 | #[inline (always)] |
1166 | fn offset_to(&self, second: &Self) -> usize { |
1167 | self.as_bytes().offset_to(second:second.as_bytes()) |
1168 | } |
1169 | } |
1170 | |
1171 | impl<'a> Offset for &'a Bytes { |
1172 | #[inline (always)] |
1173 | fn offset_to(&self, second: &Self) -> usize { |
1174 | self.as_bytes().offset_to(second:second.as_bytes()) |
1175 | } |
1176 | } |
1177 | |
1178 | impl Offset for BStr { |
1179 | #[inline (always)] |
1180 | fn offset_to(&self, second: &Self) -> usize { |
1181 | self.as_bytes().offset_to(second:second.as_bytes()) |
1182 | } |
1183 | } |
1184 | |
1185 | impl<'a> Offset for &'a BStr { |
1186 | #[inline (always)] |
1187 | fn offset_to(&self, second: &Self) -> usize { |
1188 | self.as_bytes().offset_to(second:second.as_bytes()) |
1189 | } |
1190 | } |
1191 | |
1192 | impl<I> Offset for (I, usize) |
1193 | where |
1194 | I: Offset, |
1195 | { |
1196 | #[inline (always)] |
1197 | fn offset_to(&self, other: &Self) -> usize { |
1198 | self.0.offset_to(&other.0) * 8 + other.1 - self.1 |
1199 | } |
1200 | } |
1201 | |
1202 | impl<I> Offset for Located<I> |
1203 | where |
1204 | I: Offset, |
1205 | { |
1206 | #[inline (always)] |
1207 | fn offset_to(&self, other: &Self) -> usize { |
1208 | self.input.offset_to(&other.input) |
1209 | } |
1210 | } |
1211 | |
1212 | impl<I, S> Offset for Stateful<I, S> |
1213 | where |
1214 | I: Offset, |
1215 | { |
1216 | #[inline (always)] |
1217 | fn offset_to(&self, other: &Self) -> usize { |
1218 | self.input.offset_to(&other.input) |
1219 | } |
1220 | } |
1221 | |
1222 | impl<I> Offset for Partial<I> |
1223 | where |
1224 | I: Offset, |
1225 | { |
1226 | #[inline (always)] |
1227 | fn offset_to(&self, second: &Self) -> usize { |
1228 | self.input.offset_to(&second.input) |
1229 | } |
1230 | } |
1231 | |
1232 | /// Helper trait for types that can be viewed as a byte slice |
1233 | pub trait AsBytes { |
1234 | /// Casts the input type to a byte slice |
1235 | fn as_bytes(&self) -> &[u8]; |
1236 | } |
1237 | |
1238 | impl<'a> AsBytes for &'a [u8] { |
1239 | #[inline (always)] |
1240 | fn as_bytes(&self) -> &[u8] { |
1241 | self |
1242 | } |
1243 | } |
1244 | |
1245 | impl<'a> AsBytes for &'a Bytes { |
1246 | #[inline (always)] |
1247 | fn as_bytes(&self) -> &[u8] { |
1248 | (*self).as_bytes() |
1249 | } |
1250 | } |
1251 | |
1252 | impl<I> AsBytes for Located<I> |
1253 | where |
1254 | I: AsBytes, |
1255 | { |
1256 | #[inline (always)] |
1257 | fn as_bytes(&self) -> &[u8] { |
1258 | self.input.as_bytes() |
1259 | } |
1260 | } |
1261 | |
1262 | impl<I, S> AsBytes for Stateful<I, S> |
1263 | where |
1264 | I: AsBytes, |
1265 | { |
1266 | #[inline (always)] |
1267 | fn as_bytes(&self) -> &[u8] { |
1268 | self.input.as_bytes() |
1269 | } |
1270 | } |
1271 | |
1272 | impl<I> AsBytes for Partial<I> |
1273 | where |
1274 | I: AsBytes, |
1275 | { |
1276 | #[inline (always)] |
1277 | fn as_bytes(&self) -> &[u8] { |
1278 | self.input.as_bytes() |
1279 | } |
1280 | } |
1281 | |
1282 | /// Helper trait for types that can be viewed as a byte slice |
1283 | pub trait AsBStr { |
1284 | /// Casts the input type to a byte slice |
1285 | fn as_bstr(&self) -> &[u8]; |
1286 | } |
1287 | |
1288 | impl<'a> AsBStr for &'a [u8] { |
1289 | #[inline (always)] |
1290 | fn as_bstr(&self) -> &[u8] { |
1291 | self |
1292 | } |
1293 | } |
1294 | |
1295 | impl<'a> AsBStr for &'a BStr { |
1296 | #[inline (always)] |
1297 | fn as_bstr(&self) -> &[u8] { |
1298 | (*self).as_bytes() |
1299 | } |
1300 | } |
1301 | |
1302 | impl<'a> AsBStr for &'a str { |
1303 | #[inline (always)] |
1304 | fn as_bstr(&self) -> &[u8] { |
1305 | (*self).as_bytes() |
1306 | } |
1307 | } |
1308 | |
1309 | impl<I> AsBStr for Located<I> |
1310 | where |
1311 | I: AsBStr, |
1312 | { |
1313 | #[inline (always)] |
1314 | fn as_bstr(&self) -> &[u8] { |
1315 | self.input.as_bstr() |
1316 | } |
1317 | } |
1318 | |
1319 | impl<I, S> AsBStr for Stateful<I, S> |
1320 | where |
1321 | I: AsBStr, |
1322 | { |
1323 | #[inline (always)] |
1324 | fn as_bstr(&self) -> &[u8] { |
1325 | self.input.as_bstr() |
1326 | } |
1327 | } |
1328 | |
1329 | impl<I> AsBStr for Partial<I> |
1330 | where |
1331 | I: AsBStr, |
1332 | { |
1333 | #[inline (always)] |
1334 | fn as_bstr(&self) -> &[u8] { |
1335 | self.input.as_bstr() |
1336 | } |
1337 | } |
1338 | |
1339 | /// Result of [`Compare::compare`] |
1340 | #[derive (Debug, Eq, PartialEq)] |
1341 | pub enum CompareResult { |
1342 | /// Comparison was successful |
1343 | Ok, |
1344 | /// We need more data to be sure |
1345 | Incomplete, |
1346 | /// Comparison failed |
1347 | Error, |
1348 | } |
1349 | |
1350 | /// Abstracts comparison operations |
1351 | pub trait Compare<T> { |
1352 | /// Compares self to another value for equality |
1353 | fn compare(&self, t: T) -> CompareResult; |
1354 | /// Compares self to another value for equality |
1355 | /// independently of the case. |
1356 | /// |
1357 | /// Warning: for `&str`, the comparison is done |
1358 | /// by lowercasing both strings and comparing |
1359 | /// the result. This is a temporary solution until |
1360 | /// a better one appears |
1361 | fn compare_no_case(&self, t: T) -> CompareResult; |
1362 | } |
1363 | |
1364 | fn lowercase_byte(c: u8) -> u8 { |
1365 | match c { |
1366 | b'A' ..=b'Z' => c - b'A' + b'a' , |
1367 | _ => c, |
1368 | } |
1369 | } |
1370 | |
1371 | impl<'a, 'b> Compare<&'b [u8]> for &'a [u8] { |
1372 | #[inline ] |
1373 | fn compare(&self, t: &'b [u8]) -> CompareResult { |
1374 | let pos = self.iter().zip(t.iter()).position(|(a, b)| a != b); |
1375 | |
1376 | match pos { |
1377 | Some(_) => CompareResult::Error, |
1378 | None => { |
1379 | if self.len() >= t.len() { |
1380 | CompareResult::Ok |
1381 | } else { |
1382 | CompareResult::Incomplete |
1383 | } |
1384 | } |
1385 | } |
1386 | } |
1387 | |
1388 | #[inline ] |
1389 | fn compare_no_case(&self, t: &'b [u8]) -> CompareResult { |
1390 | if self |
1391 | .iter() |
1392 | .zip(t) |
1393 | .any(|(a, b)| lowercase_byte(*a) != lowercase_byte(*b)) |
1394 | { |
1395 | CompareResult::Error |
1396 | } else if self.len() < t.len() { |
1397 | CompareResult::Incomplete |
1398 | } else { |
1399 | CompareResult::Ok |
1400 | } |
1401 | } |
1402 | } |
1403 | |
1404 | impl<'a, const LEN: usize> Compare<[u8; LEN]> for &'a [u8] { |
1405 | #[inline (always)] |
1406 | fn compare(&self, t: [u8; LEN]) -> CompareResult { |
1407 | self.compare(&t[..]) |
1408 | } |
1409 | |
1410 | #[inline (always)] |
1411 | fn compare_no_case(&self, t: [u8; LEN]) -> CompareResult { |
1412 | self.compare_no_case(&t[..]) |
1413 | } |
1414 | } |
1415 | |
1416 | impl<'a, 'b, const LEN: usize> Compare<&'b [u8; LEN]> for &'a [u8] { |
1417 | #[inline (always)] |
1418 | fn compare(&self, t: &'b [u8; LEN]) -> CompareResult { |
1419 | self.compare(&t[..]) |
1420 | } |
1421 | |
1422 | #[inline (always)] |
1423 | fn compare_no_case(&self, t: &'b [u8; LEN]) -> CompareResult { |
1424 | self.compare_no_case(&t[..]) |
1425 | } |
1426 | } |
1427 | |
1428 | impl<'a, 'b> Compare<&'b str> for &'a [u8] { |
1429 | #[inline (always)] |
1430 | fn compare(&self, t: &'b str) -> CompareResult { |
1431 | self.compare(t.as_bytes()) |
1432 | } |
1433 | #[inline (always)] |
1434 | fn compare_no_case(&self, t: &'b str) -> CompareResult { |
1435 | self.compare_no_case(t.as_bytes()) |
1436 | } |
1437 | } |
1438 | |
1439 | impl<'a, 'b> Compare<&'b str> for &'a str { |
1440 | #[inline (always)] |
1441 | fn compare(&self, t: &'b str) -> CompareResult { |
1442 | self.as_bytes().compare(t.as_bytes()) |
1443 | } |
1444 | |
1445 | //FIXME: this version is too simple and does not use the current locale |
1446 | #[inline ] |
1447 | fn compare_no_case(&self, t: &'b str) -> CompareResult { |
1448 | let pos = self |
1449 | .chars() |
1450 | .zip(t.chars()) |
1451 | .position(|(a, b)| a.to_lowercase().ne(b.to_lowercase())); |
1452 | |
1453 | match pos { |
1454 | Some(_) => CompareResult::Error, |
1455 | None => { |
1456 | if self.len() >= t.len() { |
1457 | CompareResult::Ok |
1458 | } else { |
1459 | CompareResult::Incomplete |
1460 | } |
1461 | } |
1462 | } |
1463 | } |
1464 | } |
1465 | |
1466 | impl<'a, 'b> Compare<&'b [u8]> for &'a str { |
1467 | #[inline (always)] |
1468 | fn compare(&self, t: &'b [u8]) -> CompareResult { |
1469 | AsBStr::as_bstr(self).compare(t) |
1470 | } |
1471 | #[inline (always)] |
1472 | fn compare_no_case(&self, t: &'b [u8]) -> CompareResult { |
1473 | AsBStr::as_bstr(self).compare_no_case(t) |
1474 | } |
1475 | } |
1476 | |
1477 | impl<'a, T> Compare<T> for &'a Bytes |
1478 | where |
1479 | &'a [u8]: Compare<T>, |
1480 | { |
1481 | #[inline (always)] |
1482 | fn compare(&self, t: T) -> CompareResult { |
1483 | let bytes: &[u8] = (*self).as_bytes(); |
1484 | bytes.compare(t) |
1485 | } |
1486 | |
1487 | #[inline (always)] |
1488 | fn compare_no_case(&self, t: T) -> CompareResult { |
1489 | let bytes: &[u8] = (*self).as_bytes(); |
1490 | bytes.compare_no_case(t) |
1491 | } |
1492 | } |
1493 | |
1494 | impl<'a, T> Compare<T> for &'a BStr |
1495 | where |
1496 | &'a [u8]: Compare<T>, |
1497 | { |
1498 | #[inline (always)] |
1499 | fn compare(&self, t: T) -> CompareResult { |
1500 | let bytes: &[u8] = (*self).as_bytes(); |
1501 | bytes.compare(t) |
1502 | } |
1503 | |
1504 | #[inline (always)] |
1505 | fn compare_no_case(&self, t: T) -> CompareResult { |
1506 | let bytes: &[u8] = (*self).as_bytes(); |
1507 | bytes.compare_no_case(t) |
1508 | } |
1509 | } |
1510 | |
1511 | impl<I, U> Compare<U> for Located<I> |
1512 | where |
1513 | I: Compare<U>, |
1514 | { |
1515 | #[inline (always)] |
1516 | fn compare(&self, other: U) -> CompareResult { |
1517 | self.input.compare(other) |
1518 | } |
1519 | |
1520 | #[inline (always)] |
1521 | fn compare_no_case(&self, other: U) -> CompareResult { |
1522 | self.input.compare_no_case(other) |
1523 | } |
1524 | } |
1525 | |
1526 | impl<I, S, U> Compare<U> for Stateful<I, S> |
1527 | where |
1528 | I: Compare<U>, |
1529 | { |
1530 | #[inline (always)] |
1531 | fn compare(&self, other: U) -> CompareResult { |
1532 | self.input.compare(other) |
1533 | } |
1534 | |
1535 | #[inline (always)] |
1536 | fn compare_no_case(&self, other: U) -> CompareResult { |
1537 | self.input.compare_no_case(other) |
1538 | } |
1539 | } |
1540 | |
1541 | impl<I, T> Compare<T> for Partial<I> |
1542 | where |
1543 | I: Compare<T>, |
1544 | { |
1545 | #[inline (always)] |
1546 | fn compare(&self, t: T) -> CompareResult { |
1547 | self.input.compare(t) |
1548 | } |
1549 | |
1550 | #[inline (always)] |
1551 | fn compare_no_case(&self, t: T) -> CompareResult { |
1552 | self.input.compare_no_case(t) |
1553 | } |
1554 | } |
1555 | |
1556 | /// Look for a slice in self |
1557 | pub trait FindSlice<T> { |
1558 | /// Returns the offset of the slice if it is found |
1559 | fn find_slice(&self, substr: T) -> Option<usize>; |
1560 | } |
1561 | |
1562 | impl<'i, 's> FindSlice<&'s [u8]> for &'i [u8] { |
1563 | #[inline (always)] |
1564 | fn find_slice(&self, substr: &'s [u8]) -> Option<usize> { |
1565 | memmem(self, tag:substr) |
1566 | } |
1567 | } |
1568 | |
1569 | impl<'i> FindSlice<u8> for &'i [u8] { |
1570 | #[inline (always)] |
1571 | fn find_slice(&self, substr: u8) -> Option<usize> { |
1572 | memchr(token:substr, self) |
1573 | } |
1574 | } |
1575 | |
1576 | impl<'i, 's> FindSlice<&'s str> for &'i [u8] { |
1577 | #[inline (always)] |
1578 | fn find_slice(&self, substr: &'s str) -> Option<usize> { |
1579 | self.find_slice(substr:substr.as_bytes()) |
1580 | } |
1581 | } |
1582 | |
1583 | impl<'i, 's> FindSlice<&'s str> for &'i str { |
1584 | #[inline (always)] |
1585 | fn find_slice(&self, substr: &'s str) -> Option<usize> { |
1586 | self.find(substr) |
1587 | } |
1588 | } |
1589 | |
1590 | impl<'i> FindSlice<char> for &'i str { |
1591 | #[inline (always)] |
1592 | fn find_slice(&self, substr: char) -> Option<usize> { |
1593 | self.find(substr) |
1594 | } |
1595 | } |
1596 | |
1597 | impl<'i, S> FindSlice<S> for &'i Bytes |
1598 | where |
1599 | &'i [u8]: FindSlice<S>, |
1600 | { |
1601 | #[inline (always)] |
1602 | fn find_slice(&self, substr: S) -> Option<usize> { |
1603 | let bytes: &[u8] = (*self).as_bytes(); |
1604 | let offset: Option = bytes.find_slice(substr); |
1605 | offset |
1606 | } |
1607 | } |
1608 | |
1609 | impl<'i, S> FindSlice<S> for &'i BStr |
1610 | where |
1611 | &'i [u8]: FindSlice<S>, |
1612 | { |
1613 | #[inline (always)] |
1614 | fn find_slice(&self, substr: S) -> Option<usize> { |
1615 | let bytes: &[u8] = (*self).as_bytes(); |
1616 | let offset: Option = bytes.find_slice(substr); |
1617 | offset |
1618 | } |
1619 | } |
1620 | |
1621 | impl<I, T> FindSlice<T> for Located<I> |
1622 | where |
1623 | I: FindSlice<T>, |
1624 | { |
1625 | #[inline (always)] |
1626 | fn find_slice(&self, substr: T) -> Option<usize> { |
1627 | self.input.find_slice(substr) |
1628 | } |
1629 | } |
1630 | |
1631 | impl<I, S, T> FindSlice<T> for Stateful<I, S> |
1632 | where |
1633 | I: FindSlice<T>, |
1634 | { |
1635 | #[inline (always)] |
1636 | fn find_slice(&self, substr: T) -> Option<usize> { |
1637 | self.input.find_slice(substr) |
1638 | } |
1639 | } |
1640 | |
1641 | impl<I, T> FindSlice<T> for Partial<I> |
1642 | where |
1643 | I: FindSlice<T>, |
1644 | { |
1645 | #[inline (always)] |
1646 | fn find_slice(&self, substr: T) -> Option<usize> { |
1647 | self.input.find_slice(substr) |
1648 | } |
1649 | } |
1650 | |
1651 | /// Used to integrate `str`'s `parse()` method |
1652 | pub trait ParseSlice<R> { |
1653 | /// Succeeds if `parse()` succeededThe |
1654 | /// |
1655 | /// The byte slice implementation will first convert it to a `&str`, then apply the `parse()` |
1656 | /// function |
1657 | fn parse_slice(&self) -> Option<R>; |
1658 | } |
1659 | |
1660 | impl<'a, R: FromStr> ParseSlice<R> for &'a [u8] { |
1661 | #[inline (always)] |
1662 | fn parse_slice(&self) -> Option<R> { |
1663 | from_utf8(self).ok().and_then(|s: &str| s.parse().ok()) |
1664 | } |
1665 | } |
1666 | |
1667 | impl<'a, R: FromStr> ParseSlice<R> for &'a str { |
1668 | #[inline (always)] |
1669 | fn parse_slice(&self) -> Option<R> { |
1670 | self.parse().ok() |
1671 | } |
1672 | } |
1673 | |
1674 | /// Convert a `Stream` into an appropriate `Output` type |
1675 | pub trait UpdateSlice: Stream { |
1676 | /// Convert an `Output` type to be used as `Stream` |
1677 | fn update_slice(self, inner: Self::Slice) -> Self; |
1678 | } |
1679 | |
1680 | impl<'a, T> UpdateSlice for &'a [T] |
1681 | where |
1682 | T: Clone + crate::lib::std::fmt::Debug, |
1683 | { |
1684 | #[inline (always)] |
1685 | fn update_slice(self, inner: Self::Slice) -> Self { |
1686 | inner |
1687 | } |
1688 | } |
1689 | |
1690 | impl<'a> UpdateSlice for &'a str { |
1691 | #[inline (always)] |
1692 | fn update_slice(self, inner: Self::Slice) -> Self { |
1693 | inner |
1694 | } |
1695 | } |
1696 | |
1697 | impl<'a> UpdateSlice for &'a Bytes { |
1698 | #[inline (always)] |
1699 | fn update_slice(self, inner: Self::Slice) -> Self { |
1700 | Bytes::new(bytes:inner) |
1701 | } |
1702 | } |
1703 | |
1704 | impl<'a> UpdateSlice for &'a BStr { |
1705 | #[inline (always)] |
1706 | fn update_slice(self, inner: Self::Slice) -> Self { |
1707 | BStr::new(bytes:inner) |
1708 | } |
1709 | } |
1710 | |
1711 | impl<I> UpdateSlice for Located<I> |
1712 | where |
1713 | I: UpdateSlice, |
1714 | { |
1715 | #[inline (always)] |
1716 | fn update_slice(mut self, inner: Self::Slice) -> Self { |
1717 | self.input = I::update_slice(self.input, inner); |
1718 | self |
1719 | } |
1720 | } |
1721 | |
1722 | impl<I, S> UpdateSlice for Stateful<I, S> |
1723 | where |
1724 | I: UpdateSlice, |
1725 | S: Clone + crate::lib::std::fmt::Debug, |
1726 | { |
1727 | #[inline (always)] |
1728 | fn update_slice(mut self, inner: Self::Slice) -> Self { |
1729 | self.input = I::update_slice(self.input, inner); |
1730 | self |
1731 | } |
1732 | } |
1733 | |
1734 | impl<I> UpdateSlice for Partial<I> |
1735 | where |
1736 | I: UpdateSlice, |
1737 | { |
1738 | #[inline (always)] |
1739 | fn update_slice(self, inner: Self::Slice) -> Self { |
1740 | Partial { |
1741 | input: I::update_slice(self.input, inner), |
1742 | partial: self.partial, |
1743 | } |
1744 | } |
1745 | } |
1746 | |
1747 | /// A range bounded inclusively for counting parses performed |
1748 | #[derive (PartialEq, Eq)] |
1749 | pub struct Range { |
1750 | pub(crate) start_inclusive: usize, |
1751 | pub(crate) end_inclusive: Option<usize>, |
1752 | } |
1753 | |
1754 | impl Range { |
1755 | #[inline (always)] |
1756 | fn raw(start_inclusive: usize, end_inclusive: Option<usize>) -> Self { |
1757 | Self { |
1758 | start_inclusive, |
1759 | end_inclusive, |
1760 | } |
1761 | } |
1762 | } |
1763 | |
1764 | impl crate::lib::std::ops::RangeBounds<usize> for Range { |
1765 | #[inline (always)] |
1766 | fn start_bound(&self) -> crate::lib::std::ops::Bound<&usize> { |
1767 | crate::lib::std::ops::Bound::Included(&self.start_inclusive) |
1768 | } |
1769 | |
1770 | #[inline (always)] |
1771 | fn end_bound(&self) -> crate::lib::std::ops::Bound<&usize> { |
1772 | if let Some(end_inclusive: &usize) = &self.end_inclusive { |
1773 | crate::lib::std::ops::Bound::Included(end_inclusive) |
1774 | } else { |
1775 | crate::lib::std::ops::Bound::Unbounded |
1776 | } |
1777 | } |
1778 | } |
1779 | |
1780 | impl From<usize> for Range { |
1781 | #[inline (always)] |
1782 | fn from(fixed: usize) -> Self { |
1783 | (fixed..=fixed).into() |
1784 | } |
1785 | } |
1786 | |
1787 | impl From<crate::lib::std::ops::Range<usize>> for Range { |
1788 | #[inline (always)] |
1789 | fn from(range: crate::lib::std::ops::Range<usize>) -> Self { |
1790 | let start_inclusive: usize = range.start; |
1791 | let end_inclusive: Option = Some(range.end.saturating_sub(1)); |
1792 | Self::raw(start_inclusive, end_inclusive) |
1793 | } |
1794 | } |
1795 | |
1796 | impl From<crate::lib::std::ops::RangeFull> for Range { |
1797 | #[inline (always)] |
1798 | fn from(_: crate::lib::std::ops::RangeFull) -> Self { |
1799 | let start_inclusive: usize = 0; |
1800 | let end_inclusive: Option = None; |
1801 | Self::raw(start_inclusive, end_inclusive) |
1802 | } |
1803 | } |
1804 | |
1805 | impl From<crate::lib::std::ops::RangeFrom<usize>> for Range { |
1806 | #[inline (always)] |
1807 | fn from(range: crate::lib::std::ops::RangeFrom<usize>) -> Self { |
1808 | let start_inclusive: usize = range.start; |
1809 | let end_inclusive: Option = None; |
1810 | Self::raw(start_inclusive, end_inclusive) |
1811 | } |
1812 | } |
1813 | |
1814 | impl From<crate::lib::std::ops::RangeTo<usize>> for Range { |
1815 | #[inline (always)] |
1816 | fn from(range: crate::lib::std::ops::RangeTo<usize>) -> Self { |
1817 | let start_inclusive: usize = 0; |
1818 | let end_inclusive: Option = Some(range.end.saturating_sub(1)); |
1819 | Self::raw(start_inclusive, end_inclusive) |
1820 | } |
1821 | } |
1822 | |
1823 | impl From<crate::lib::std::ops::RangeInclusive<usize>> for Range { |
1824 | #[inline (always)] |
1825 | fn from(range: crate::lib::std::ops::RangeInclusive<usize>) -> Self { |
1826 | let start_inclusive: usize = *range.start(); |
1827 | let end_inclusive: Option = Some(*range.end()); |
1828 | Self::raw(start_inclusive, end_inclusive) |
1829 | } |
1830 | } |
1831 | |
1832 | impl From<crate::lib::std::ops::RangeToInclusive<usize>> for Range { |
1833 | #[inline (always)] |
1834 | fn from(range: crate::lib::std::ops::RangeToInclusive<usize>) -> Self { |
1835 | let start_inclusive: usize = 0; |
1836 | let end_inclusive: Option = Some(range.end); |
1837 | Self::raw(start_inclusive, end_inclusive) |
1838 | } |
1839 | } |
1840 | |
1841 | impl crate::lib::std::fmt::Display for Range { |
1842 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
1843 | self.start_inclusive.fmt(f)?; |
1844 | match self.end_inclusive { |
1845 | Some(e: usize) if e == self.start_inclusive => {} |
1846 | Some(e: usize) => { |
1847 | "..=" .fmt(f)?; |
1848 | e.fmt(f)?; |
1849 | } |
1850 | None => { |
1851 | ".." .fmt(f)?; |
1852 | } |
1853 | } |
1854 | Ok(()) |
1855 | } |
1856 | } |
1857 | |
1858 | impl crate::lib::std::fmt::Debug for Range { |
1859 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
1860 | write!(f, " {self}" ) |
1861 | } |
1862 | } |
1863 | |
1864 | /// Abstracts something which can extend an `Extend`. |
1865 | /// Used to build modified input slices in `escaped_transform` |
1866 | pub trait Accumulate<T>: Sized { |
1867 | /// Create a new `Extend` of the correct type |
1868 | fn initial(capacity: Option<usize>) -> Self; |
1869 | /// Accumulate the input into an accumulator |
1870 | fn accumulate(&mut self, acc: T); |
1871 | } |
1872 | |
1873 | impl<T> Accumulate<T> for () { |
1874 | #[inline (always)] |
1875 | fn initial(_capacity: Option<usize>) -> Self {} |
1876 | #[inline (always)] |
1877 | fn accumulate(&mut self, _acc: T) {} |
1878 | } |
1879 | |
1880 | impl<T> Accumulate<T> for usize { |
1881 | #[inline (always)] |
1882 | fn initial(_capacity: Option<usize>) -> Self { |
1883 | 0 |
1884 | } |
1885 | #[inline (always)] |
1886 | fn accumulate(&mut self, _acc: T) { |
1887 | *self += 1; |
1888 | } |
1889 | } |
1890 | |
1891 | #[cfg (feature = "alloc" )] |
1892 | impl<T> Accumulate<T> for Vec<T> { |
1893 | #[inline (always)] |
1894 | fn initial(capacity: Option<usize>) -> Self { |
1895 | match capacity { |
1896 | Some(capacity: usize) => Vec::with_capacity(clamp_capacity::<T>(capacity)), |
1897 | None => Vec::new(), |
1898 | } |
1899 | } |
1900 | #[inline (always)] |
1901 | fn accumulate(&mut self, acc: T) { |
1902 | self.push(acc); |
1903 | } |
1904 | } |
1905 | |
1906 | #[cfg (feature = "alloc" )] |
1907 | impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> { |
1908 | #[inline (always)] |
1909 | fn initial(capacity: Option<usize>) -> Self { |
1910 | match capacity { |
1911 | Some(capacity: usize) => Vec::with_capacity(clamp_capacity::<T>(capacity)), |
1912 | None => Vec::new(), |
1913 | } |
1914 | } |
1915 | #[inline (always)] |
1916 | fn accumulate(&mut self, acc: &'i [T]) { |
1917 | self.extend(iter:acc.iter().cloned()); |
1918 | } |
1919 | } |
1920 | |
1921 | #[cfg (feature = "alloc" )] |
1922 | impl Accumulate<char> for String { |
1923 | #[inline (always)] |
1924 | fn initial(capacity: Option<usize>) -> Self { |
1925 | match capacity { |
1926 | Some(capacity: usize) => String::with_capacity(clamp_capacity::<char>(capacity)), |
1927 | None => String::new(), |
1928 | } |
1929 | } |
1930 | #[inline (always)] |
1931 | fn accumulate(&mut self, acc: char) { |
1932 | self.push(ch:acc); |
1933 | } |
1934 | } |
1935 | |
1936 | #[cfg (feature = "alloc" )] |
1937 | impl<'i> Accumulate<&'i str> for String { |
1938 | #[inline (always)] |
1939 | fn initial(capacity: Option<usize>) -> Self { |
1940 | match capacity { |
1941 | Some(capacity: usize) => String::with_capacity(clamp_capacity::<char>(capacity)), |
1942 | None => String::new(), |
1943 | } |
1944 | } |
1945 | #[inline (always)] |
1946 | fn accumulate(&mut self, acc: &'i str) { |
1947 | self.push_str(string:acc); |
1948 | } |
1949 | } |
1950 | |
1951 | #[cfg (feature = "alloc" )] |
1952 | impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V> |
1953 | where |
1954 | K: crate::lib::std::cmp::Ord, |
1955 | { |
1956 | #[inline (always)] |
1957 | fn initial(_capacity: Option<usize>) -> Self { |
1958 | BTreeMap::new() |
1959 | } |
1960 | #[inline (always)] |
1961 | fn accumulate(&mut self, (key: K, value: V): (K, V)) { |
1962 | self.insert(key, value); |
1963 | } |
1964 | } |
1965 | |
1966 | #[cfg (feature = "std" )] |
1967 | impl<K, V> Accumulate<(K, V)> for HashMap<K, V> |
1968 | where |
1969 | K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash, |
1970 | { |
1971 | #[inline (always)] |
1972 | fn initial(capacity: Option<usize>) -> Self { |
1973 | match capacity { |
1974 | Some(capacity: usize) => HashMap::with_capacity(clamp_capacity::<(K, V)>(capacity)), |
1975 | None => HashMap::new(), |
1976 | } |
1977 | } |
1978 | #[inline (always)] |
1979 | fn accumulate(&mut self, (key: K, value: V): (K, V)) { |
1980 | self.insert(k:key, v:value); |
1981 | } |
1982 | } |
1983 | |
1984 | #[cfg (feature = "alloc" )] |
1985 | #[inline ] |
1986 | pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize { |
1987 | /// Don't pre-allocate more than 64KiB when calling `Vec::with_capacity`. |
1988 | /// |
1989 | /// Pre-allocating memory is a nice optimization but count fields can't |
1990 | /// always be trusted. We should clamp initial capacities to some reasonable |
1991 | /// amount. This reduces the risk of a bogus count value triggering a panic |
1992 | /// due to an OOM error. |
1993 | /// |
1994 | /// This does not affect correctness. `winnow` will always read the full number |
1995 | /// of elements regardless of the capacity cap. |
1996 | const MAX_INITIAL_CAPACITY_BYTES: usize = 65536; |
1997 | |
1998 | let max_initial_capacity: usize = |
1999 | MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<T>().max(1); |
2000 | capacity.min(max_initial_capacity) |
2001 | } |
2002 | |
2003 | /// Helper trait to convert numbers to usize. |
2004 | /// |
2005 | /// By default, usize implements `From<u8>` and `From<u16>` but not |
2006 | /// `From<u32>` and `From<u64>` because that would be invalid on some |
2007 | /// platforms. This trait implements the conversion for platforms |
2008 | /// with 32 and 64 bits pointer platforms |
2009 | pub trait ToUsize { |
2010 | /// converts self to usize |
2011 | fn to_usize(&self) -> usize; |
2012 | } |
2013 | |
2014 | impl ToUsize for u8 { |
2015 | #[inline (always)] |
2016 | fn to_usize(&self) -> usize { |
2017 | *self as usize |
2018 | } |
2019 | } |
2020 | |
2021 | impl ToUsize for u16 { |
2022 | #[inline (always)] |
2023 | fn to_usize(&self) -> usize { |
2024 | *self as usize |
2025 | } |
2026 | } |
2027 | |
2028 | impl ToUsize for usize { |
2029 | #[inline (always)] |
2030 | fn to_usize(&self) -> usize { |
2031 | *self |
2032 | } |
2033 | } |
2034 | |
2035 | #[cfg (any(target_pointer_width = "32" , target_pointer_width = "64" ))] |
2036 | impl ToUsize for u32 { |
2037 | #[inline (always)] |
2038 | fn to_usize(&self) -> usize { |
2039 | *self as usize |
2040 | } |
2041 | } |
2042 | |
2043 | #[cfg (target_pointer_width = "64" )] |
2044 | impl ToUsize for u64 { |
2045 | #[inline (always)] |
2046 | fn to_usize(&self) -> usize { |
2047 | *self as usize |
2048 | } |
2049 | } |
2050 | |
2051 | /// Transforms a token into a char for basic string parsing |
2052 | #[allow (clippy::len_without_is_empty)] |
2053 | #[allow (clippy::wrong_self_convention)] |
2054 | pub trait AsChar { |
2055 | /// Makes a char from self |
2056 | /// |
2057 | /// # Example |
2058 | /// |
2059 | /// ``` |
2060 | /// use winnow::stream::AsChar as _; |
2061 | /// |
2062 | /// assert_eq!('a' .as_char(), 'a' ); |
2063 | /// assert_eq!(u8::MAX.as_char(), std::char::from_u32(u8::MAX as u32).unwrap()); |
2064 | /// ``` |
2065 | fn as_char(self) -> char; |
2066 | |
2067 | /// Tests that self is an alphabetic character |
2068 | /// |
2069 | /// **Warning:** for `&str` it recognizes alphabetic |
2070 | /// characters outside of the 52 ASCII letters |
2071 | fn is_alpha(self) -> bool; |
2072 | |
2073 | /// Tests that self is an alphabetic character |
2074 | /// or a decimal digit |
2075 | fn is_alphanum(self) -> bool; |
2076 | /// Tests that self is a decimal digit |
2077 | fn is_dec_digit(self) -> bool; |
2078 | /// Tests that self is an hex digit |
2079 | fn is_hex_digit(self) -> bool; |
2080 | /// Tests that self is an octal digit |
2081 | fn is_oct_digit(self) -> bool; |
2082 | /// Gets the len in bytes for self |
2083 | fn len(self) -> usize; |
2084 | /// Tests that self is ASCII space or tab |
2085 | fn is_space(self) -> bool; |
2086 | /// Tests if byte is ASCII newline: \n |
2087 | fn is_newline(self) -> bool; |
2088 | } |
2089 | |
2090 | impl AsChar for u8 { |
2091 | #[inline (always)] |
2092 | fn as_char(self) -> char { |
2093 | self as char |
2094 | } |
2095 | #[inline ] |
2096 | fn is_alpha(self) -> bool { |
2097 | matches!(self, 0x41..=0x5A | 0x61..=0x7A) |
2098 | } |
2099 | #[inline ] |
2100 | fn is_alphanum(self) -> bool { |
2101 | self.is_alpha() || self.is_dec_digit() |
2102 | } |
2103 | #[inline ] |
2104 | fn is_dec_digit(self) -> bool { |
2105 | matches!(self, 0x30..=0x39) |
2106 | } |
2107 | #[inline ] |
2108 | fn is_hex_digit(self) -> bool { |
2109 | matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66) |
2110 | } |
2111 | #[inline ] |
2112 | fn is_oct_digit(self) -> bool { |
2113 | matches!(self, 0x30..=0x37) |
2114 | } |
2115 | #[inline ] |
2116 | fn len(self) -> usize { |
2117 | 1 |
2118 | } |
2119 | #[inline ] |
2120 | fn is_space(self) -> bool { |
2121 | self == b' ' || self == b' \t' |
2122 | } |
2123 | #[inline ] |
2124 | fn is_newline(self) -> bool { |
2125 | self == b' \n' |
2126 | } |
2127 | } |
2128 | impl<'a> AsChar for &'a u8 { |
2129 | #[inline (always)] |
2130 | fn as_char(self) -> char { |
2131 | *self as char |
2132 | } |
2133 | #[inline ] |
2134 | fn is_alpha(self) -> bool { |
2135 | matches!(*self, 0x41..=0x5A | 0x61..=0x7A) |
2136 | } |
2137 | #[inline ] |
2138 | fn is_alphanum(self) -> bool { |
2139 | self.is_alpha() || self.is_dec_digit() |
2140 | } |
2141 | #[inline ] |
2142 | fn is_dec_digit(self) -> bool { |
2143 | matches!(*self, 0x30..=0x39) |
2144 | } |
2145 | #[inline ] |
2146 | fn is_hex_digit(self) -> bool { |
2147 | matches!(*self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66) |
2148 | } |
2149 | #[inline ] |
2150 | fn is_oct_digit(self) -> bool { |
2151 | matches!(*self, 0x30..=0x37) |
2152 | } |
2153 | #[inline ] |
2154 | fn len(self) -> usize { |
2155 | 1 |
2156 | } |
2157 | #[inline ] |
2158 | fn is_space(self) -> bool { |
2159 | *self == b' ' || *self == b' \t' |
2160 | } |
2161 | #[inline ] |
2162 | fn is_newline(self) -> bool { |
2163 | *self == b' \n' |
2164 | } |
2165 | } |
2166 | |
2167 | impl AsChar for char { |
2168 | #[inline (always)] |
2169 | fn as_char(self) -> char { |
2170 | self |
2171 | } |
2172 | #[inline ] |
2173 | fn is_alpha(self) -> bool { |
2174 | self.is_ascii_alphabetic() |
2175 | } |
2176 | #[inline ] |
2177 | fn is_alphanum(self) -> bool { |
2178 | self.is_alpha() || self.is_dec_digit() |
2179 | } |
2180 | #[inline ] |
2181 | fn is_dec_digit(self) -> bool { |
2182 | self.is_ascii_digit() |
2183 | } |
2184 | #[inline ] |
2185 | fn is_hex_digit(self) -> bool { |
2186 | self.is_ascii_hexdigit() |
2187 | } |
2188 | #[inline ] |
2189 | fn is_oct_digit(self) -> bool { |
2190 | self.is_digit(8) |
2191 | } |
2192 | #[inline ] |
2193 | fn len(self) -> usize { |
2194 | self.len_utf8() |
2195 | } |
2196 | #[inline ] |
2197 | fn is_space(self) -> bool { |
2198 | self == ' ' || self == ' \t' |
2199 | } |
2200 | #[inline ] |
2201 | fn is_newline(self) -> bool { |
2202 | self == ' \n' |
2203 | } |
2204 | } |
2205 | |
2206 | impl<'a> AsChar for &'a char { |
2207 | #[inline (always)] |
2208 | fn as_char(self) -> char { |
2209 | *self |
2210 | } |
2211 | #[inline ] |
2212 | fn is_alpha(self) -> bool { |
2213 | self.is_ascii_alphabetic() |
2214 | } |
2215 | #[inline ] |
2216 | fn is_alphanum(self) -> bool { |
2217 | self.is_alpha() || self.is_dec_digit() |
2218 | } |
2219 | #[inline ] |
2220 | fn is_dec_digit(self) -> bool { |
2221 | self.is_ascii_digit() |
2222 | } |
2223 | #[inline ] |
2224 | fn is_hex_digit(self) -> bool { |
2225 | self.is_ascii_hexdigit() |
2226 | } |
2227 | #[inline ] |
2228 | fn is_oct_digit(self) -> bool { |
2229 | self.is_digit(8) |
2230 | } |
2231 | #[inline ] |
2232 | fn len(self) -> usize { |
2233 | self.len_utf8() |
2234 | } |
2235 | #[inline ] |
2236 | fn is_space(self) -> bool { |
2237 | *self == ' ' || *self == ' \t' |
2238 | } |
2239 | #[inline ] |
2240 | fn is_newline(self) -> bool { |
2241 | *self == ' \n' |
2242 | } |
2243 | } |
2244 | |
2245 | /// Check if a token in in a set of possible tokens |
2246 | /// |
2247 | /// This is generally implemented on patterns that a token may match and supports `u8` and `char` |
2248 | /// tokens along with the following patterns |
2249 | /// - `b'c'` and `'c'` |
2250 | /// - `b""` and `""` |
2251 | /// - `|c| true` |
2252 | /// - `b'a'..=b'z'`, `'a'..='z'` (etc for each [range type][std::ops]) |
2253 | /// - `(pattern1, pattern2, ...)` |
2254 | /// |
2255 | /// # Example |
2256 | /// |
2257 | /// For example, you could implement `hex_digit0` as: |
2258 | /// ``` |
2259 | /// # use winnow::prelude::*; |
2260 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; |
2261 | /// # use winnow::token::take_while; |
2262 | /// fn hex_digit1(input: &str) -> IResult<&str, &str> { |
2263 | /// take_while(1.., ('a' ..='f' , 'A' ..='F' , '0' ..='9' )).parse_next(input) |
2264 | /// } |
2265 | /// |
2266 | /// assert_eq!(hex_digit1("21cZ" ), Ok(("Z" , "21c" ))); |
2267 | /// assert_eq!(hex_digit1("H2" ), Err(ErrMode::Backtrack(Error::new("H2" , ErrorKind::Slice)))); |
2268 | /// assert_eq!(hex_digit1("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Slice)))); |
2269 | /// ``` |
2270 | pub trait ContainsToken<T> { |
2271 | /// Returns true if self contains the token |
2272 | fn contains_token(&self, token: T) -> bool; |
2273 | } |
2274 | |
2275 | impl ContainsToken<u8> for u8 { |
2276 | #[inline (always)] |
2277 | fn contains_token(&self, token: u8) -> bool { |
2278 | *self == token |
2279 | } |
2280 | } |
2281 | |
2282 | impl<'a> ContainsToken<&'a u8> for u8 { |
2283 | #[inline (always)] |
2284 | fn contains_token(&self, token: &u8) -> bool { |
2285 | self.contains_token(*token) |
2286 | } |
2287 | } |
2288 | |
2289 | impl ContainsToken<char> for u8 { |
2290 | #[inline (always)] |
2291 | fn contains_token(&self, token: char) -> bool { |
2292 | self.as_char() == token |
2293 | } |
2294 | } |
2295 | |
2296 | impl<'a> ContainsToken<&'a char> for u8 { |
2297 | #[inline (always)] |
2298 | fn contains_token(&self, token: &char) -> bool { |
2299 | self.contains_token(*token) |
2300 | } |
2301 | } |
2302 | |
2303 | impl<C: AsChar> ContainsToken<C> for char { |
2304 | #[inline (always)] |
2305 | fn contains_token(&self, token: C) -> bool { |
2306 | *self == token.as_char() |
2307 | } |
2308 | } |
2309 | |
2310 | impl<C: AsChar, F: Fn(C) -> bool> ContainsToken<C> for F { |
2311 | #[inline (always)] |
2312 | fn contains_token(&self, token: C) -> bool { |
2313 | self(token) |
2314 | } |
2315 | } |
2316 | |
2317 | impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::Range<C2> { |
2318 | #[inline (always)] |
2319 | fn contains_token(&self, token: C1) -> bool { |
2320 | let start: char = self.start.clone().as_char(); |
2321 | let end: char = self.end.clone().as_char(); |
2322 | (start..end).contains(&token.as_char()) |
2323 | } |
2324 | } |
2325 | |
2326 | impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> |
2327 | for crate::lib::std::ops::RangeInclusive<C2> |
2328 | { |
2329 | #[inline (always)] |
2330 | fn contains_token(&self, token: C1) -> bool { |
2331 | let start: char = self.start().clone().as_char(); |
2332 | let end: char = self.end().clone().as_char(); |
2333 | (start..=end).contains(&token.as_char()) |
2334 | } |
2335 | } |
2336 | |
2337 | impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeFrom<C2> { |
2338 | #[inline (always)] |
2339 | fn contains_token(&self, token: C1) -> bool { |
2340 | let start: char = self.start.clone().as_char(); |
2341 | (start..).contains(&token.as_char()) |
2342 | } |
2343 | } |
2344 | |
2345 | impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeTo<C2> { |
2346 | #[inline (always)] |
2347 | fn contains_token(&self, token: C1) -> bool { |
2348 | let end: char = self.end.clone().as_char(); |
2349 | (..end).contains(&token.as_char()) |
2350 | } |
2351 | } |
2352 | |
2353 | impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> |
2354 | for crate::lib::std::ops::RangeToInclusive<C2> |
2355 | { |
2356 | #[inline (always)] |
2357 | fn contains_token(&self, token: C1) -> bool { |
2358 | let end: char = self.end.clone().as_char(); |
2359 | (..=end).contains(&token.as_char()) |
2360 | } |
2361 | } |
2362 | |
2363 | impl<C1: AsChar> ContainsToken<C1> for crate::lib::std::ops::RangeFull { |
2364 | #[inline (always)] |
2365 | fn contains_token(&self, _token: C1) -> bool { |
2366 | true |
2367 | } |
2368 | } |
2369 | |
2370 | impl<C: AsChar> ContainsToken<C> for &'_ [u8] { |
2371 | #[inline ] |
2372 | fn contains_token(&self, token: C) -> bool { |
2373 | let token: char = token.as_char(); |
2374 | self.iter().any(|t: &u8| t.as_char() == token) |
2375 | } |
2376 | } |
2377 | |
2378 | impl<C: AsChar> ContainsToken<C> for &'_ [char] { |
2379 | #[inline ] |
2380 | fn contains_token(&self, token: C) -> bool { |
2381 | let token: char = token.as_char(); |
2382 | self.iter().any(|t: &char| *t == token) |
2383 | } |
2384 | } |
2385 | |
2386 | impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] { |
2387 | #[inline ] |
2388 | fn contains_token(&self, token: C) -> bool { |
2389 | let token: char = token.as_char(); |
2390 | self.iter().any(|t: &u8| t.as_char() == token) |
2391 | } |
2392 | } |
2393 | |
2394 | impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] { |
2395 | #[inline ] |
2396 | fn contains_token(&self, token: C) -> bool { |
2397 | let token: char = token.as_char(); |
2398 | self.iter().any(|t: &char| *t == token) |
2399 | } |
2400 | } |
2401 | |
2402 | impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] { |
2403 | #[inline ] |
2404 | fn contains_token(&self, token: C) -> bool { |
2405 | let token: char = token.as_char(); |
2406 | self.iter().any(|t: &u8| t.as_char() == token) |
2407 | } |
2408 | } |
2409 | |
2410 | impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] { |
2411 | #[inline ] |
2412 | fn contains_token(&self, token: C) -> bool { |
2413 | let token: char = token.as_char(); |
2414 | self.iter().any(|t: &char| *t == token) |
2415 | } |
2416 | } |
2417 | |
2418 | impl<C: AsChar> ContainsToken<C> for &'_ str { |
2419 | #[inline (always)] |
2420 | fn contains_token(&self, token: C) -> bool { |
2421 | let token: char = token.as_char(); |
2422 | self.chars().any(|i: char| i == token) |
2423 | } |
2424 | } |
2425 | |
2426 | impl<T> ContainsToken<T> for () { |
2427 | #[inline (always)] |
2428 | fn contains_token(&self, _token: T) -> bool { |
2429 | false |
2430 | } |
2431 | } |
2432 | |
2433 | macro_rules! impl_contains_token_for_tuple { |
2434 | ($($haystack:ident),+) => ( |
2435 | #[allow(non_snake_case)] |
2436 | impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,) |
2437 | where |
2438 | T: Clone, |
2439 | $($haystack: ContainsToken<T>),+ |
2440 | { |
2441 | #[inline] |
2442 | fn contains_token(&self, token: T) -> bool { |
2443 | let ($(ref $haystack),+,) = *self; |
2444 | $($haystack.contains_token(token.clone()) || )+ false |
2445 | } |
2446 | } |
2447 | ) |
2448 | } |
2449 | |
2450 | macro_rules! impl_contains_token_for_tuples { |
2451 | ($haystack1:ident, $($haystack:ident),+) => { |
2452 | impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+); |
2453 | }; |
2454 | (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => { |
2455 | impl_contains_token_for_tuple!($($haystack),+); |
2456 | impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*); |
2457 | }; |
2458 | (__impl $($haystack:ident),+;) => { |
2459 | impl_contains_token_for_tuple!($($haystack),+); |
2460 | } |
2461 | } |
2462 | |
2463 | impl_contains_token_for_tuples!( |
2464 | F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21 |
2465 | ); |
2466 | |
2467 | /// Looks for the first element of the input type for which the condition returns true, |
2468 | /// and returns the input up to this position. |
2469 | /// |
2470 | /// *Partial version*: If no element is found matching the condition, this will return `Incomplete` |
2471 | pub(crate) fn split_at_offset_partial<P, I: Stream, E: ParseError<I>>( |
2472 | input: &I, |
2473 | predicate: P, |
2474 | ) -> IResult<I, <I as Stream>::Slice, E> |
2475 | where |
2476 | P: Fn(I::Token) -> bool, |
2477 | { |
2478 | let offset: usize = input |
2479 | .offset_for(predicate) |
2480 | .ok_or_else(|| ErrMode::Incomplete(Needed::new(1)))?; |
2481 | Ok(input.next_slice(offset)) |
2482 | } |
2483 | |
2484 | /// Looks for the first element of the input type for which the condition returns true |
2485 | /// and returns the input up to this position. |
2486 | /// |
2487 | /// Fails if the produced slice is empty. |
2488 | /// |
2489 | /// *Partial version*: If no element is found matching the condition, this will return `Incomplete` |
2490 | pub(crate) fn split_at_offset1_partial<P, I: Stream, E: ParseError<I>>( |
2491 | input: &I, |
2492 | predicate: P, |
2493 | e: ErrorKind, |
2494 | ) -> IResult<I, <I as Stream>::Slice, E> |
2495 | where |
2496 | P: Fn(I::Token) -> bool, |
2497 | { |
2498 | let offset: usize = input |
2499 | .offset_for(predicate) |
2500 | .ok_or_else(|| ErrMode::Incomplete(Needed::new(1)))?; |
2501 | if offset == 0 { |
2502 | Err(ErrMode::from_error_kind(input.clone(), kind:e)) |
2503 | } else { |
2504 | Ok(input.next_slice(offset)) |
2505 | } |
2506 | } |
2507 | |
2508 | /// Looks for the first element of the input type for which the condition returns true, |
2509 | /// and returns the input up to this position. |
2510 | /// |
2511 | /// *Complete version*: If no element is found matching the condition, this will return the whole input |
2512 | pub(crate) fn split_at_offset_complete<P, I: Stream, E: ParseError<I>>( |
2513 | input: &I, |
2514 | predicate: P, |
2515 | ) -> IResult<I, <I as Stream>::Slice, E> |
2516 | where |
2517 | P: Fn(I::Token) -> bool, |
2518 | { |
2519 | let offset: usize = inputOption |
2520 | .offset_for(predicate) |
2521 | .unwrap_or_else(|| input.eof_offset()); |
2522 | Ok(input.next_slice(offset)) |
2523 | } |
2524 | |
2525 | /// Looks for the first element of the input type for which the condition returns true |
2526 | /// and returns the input up to this position. |
2527 | /// |
2528 | /// Fails if the produced slice is empty. |
2529 | /// |
2530 | /// *Complete version*: If no element is found matching the condition, this will return the whole input |
2531 | pub(crate) fn split_at_offset1_complete<P, I: Stream, E: ParseError<I>>( |
2532 | input: &I, |
2533 | predicate: P, |
2534 | e: ErrorKind, |
2535 | ) -> IResult<I, <I as Stream>::Slice, E> |
2536 | where |
2537 | P: Fn(I::Token) -> bool, |
2538 | { |
2539 | let offset: usize = inputOption |
2540 | .offset_for(predicate) |
2541 | .unwrap_or_else(|| input.eof_offset()); |
2542 | if offset == 0 { |
2543 | Err(ErrMode::from_error_kind(input.clone(), kind:e)) |
2544 | } else { |
2545 | Ok(input.next_slice(offset)) |
2546 | } |
2547 | } |
2548 | |
2549 | #[cfg (feature = "simd" )] |
2550 | #[inline (always)] |
2551 | fn memchr(token: u8, slice: &[u8]) -> Option<usize> { |
2552 | memchr::memchr(token, slice) |
2553 | } |
2554 | |
2555 | #[cfg (not(feature = "simd" ))] |
2556 | #[inline (always)] |
2557 | fn memchr(token: u8, slice: &[u8]) -> Option<usize> { |
2558 | slice.iter().position(|t: &u8| *t == token) |
2559 | } |
2560 | |
2561 | #[cfg (feature = "simd" )] |
2562 | #[inline (always)] |
2563 | fn memmem(slice: &[u8], tag: &[u8]) -> Option<usize> { |
2564 | memchr::memmem::find(slice, tag) |
2565 | } |
2566 | |
2567 | #[cfg (not(feature = "simd" ))] |
2568 | fn memmem(slice: &[u8], tag: &[u8]) -> Option<usize> { |
2569 | for i: usize in 0..slice.len() { |
2570 | let subslice: &[u8] = &slice[i..]; |
2571 | if subslice.starts_with(needle:tag) { |
2572 | return Some(i); |
2573 | } |
2574 | } |
2575 | None |
2576 | } |
2577 | |