summaryrefslogtreecommitdiffstats
path: root/vendor/winnow/src/binary/bits/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/winnow/src/binary/bits/mod.rs')
-rw-r--r--vendor/winnow/src/binary/bits/mod.rs189
1 files changed, 102 insertions, 87 deletions
diff --git a/vendor/winnow/src/binary/bits/mod.rs b/vendor/winnow/src/binary/bits/mod.rs
index 5400e3308..334c6bf00 100644
--- a/vendor/winnow/src/binary/bits/mod.rs
+++ b/vendor/winnow/src/binary/bits/mod.rs
@@ -4,11 +4,11 @@
#[cfg(test)]
mod tests;
-use crate::error::{ErrMode, ErrorConvert, ErrorKind, Needed, ParseError};
+use crate::error::{ErrMode, ErrorConvert, ErrorKind, Needed, ParserError};
use crate::lib::std::ops::{AddAssign, Div, Shl, Shr};
use crate::stream::{AsBytes, Stream, StreamIsPartial, ToUsize};
use crate::trace::trace;
-use crate::{IResult, Parser};
+use crate::{unpeek, IResult, PResult, Parser};
/// Converts a byte-level input to a bit-level input
///
@@ -19,7 +19,7 @@ use crate::{IResult, Parser};
/// use winnow::prelude::*;
/// use winnow::Bytes;
/// use winnow::binary::bits::{bits, take};
-/// use winnow::error::Error;
+/// use winnow::error::InputError;
///
/// type Stream<'i> = &'i Bytes;
///
@@ -28,7 +28,7 @@ use crate::{IResult, Parser};
/// }
///
/// fn parse(input: Stream<'_>) -> IResult<Stream<'_>, (u8, u8)> {
-/// bits::<_, _, Error<(_, usize)>, _, _>((take(4usize), take(8usize))).parse_next(input)
+/// bits::<_, _, InputError<(_, usize)>, _, _>((take(4usize), take(8usize))).parse_peek(input)
/// }
///
/// let input = stream(&[0x12, 0x34, 0xff, 0xff]);
@@ -45,25 +45,28 @@ use crate::{IResult, Parser};
/// ```
pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl Parser<I, O, E2>
where
- E1: ParseError<(I, usize)> + ErrorConvert<E2>,
- E2: ParseError<I>,
- I: Stream,
+ E1: ParserError<(I, usize)> + ErrorConvert<E2>,
+ E2: ParserError<I>,
+ I: Stream + Clone,
P: Parser<(I, usize), O, E1>,
{
- trace("bits", move |input: I| {
- match parser.parse_next((input, 0)) {
- Ok(((rest, offset), result)) => {
- // If the next byte has been partially read, it will be sliced away as well.
- // The parser functions might already slice away all fully read bytes.
- // That's why `offset / 8` isn't necessarily needed at all times.
- let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 };
- let (input, _) = rest.next_slice(remaining_bytes_index);
- Ok((input, result))
+ trace(
+ "bits",
+ unpeek(move |input: I| {
+ match parser.parse_peek((input, 0)) {
+ Ok(((rest, offset), result)) => {
+ // If the next byte has been partially read, it will be sliced away as well.
+ // The parser functions might already slice away all fully read bytes.
+ // That's why `offset / 8` isn't necessarily needed at all times.
+ let remaining_bytes_index = offset / 8 + if offset % 8 == 0 { 0 } else { 1 };
+ let (input, _) = rest.peek_slice(remaining_bytes_index);
+ Ok((input, result))
+ }
+ Err(ErrMode::Incomplete(n)) => Err(ErrMode::Incomplete(n.map(|u| u.get() / 8 + 1))),
+ Err(e) => Err(e.convert()),
}
- Err(ErrMode::Incomplete(n)) => Err(ErrMode::Incomplete(n.map(|u| u.get() / 8 + 1))),
- Err(e) => Err(e.convert()),
- }
- })
+ }),
+ )
}
/// Convert a [`bits`] stream back into a byte stream
@@ -76,7 +79,7 @@ where
/// use winnow::Bytes;
/// use winnow::binary::bits::{bits, bytes, take};
/// use winnow::combinator::rest;
-/// use winnow::error::Error;
+/// use winnow::error::InputError;
///
/// type Stream<'i> = &'i Bytes;
///
@@ -85,11 +88,11 @@ where
/// }
///
/// fn parse(input: Stream<'_>) -> IResult<Stream<'_>, (u8, u8, &[u8])> {
-/// bits::<_, _, Error<(_, usize)>, _, _>((
+/// bits::<_, _, InputError<(_, usize)>, _, _>((
/// take(4usize),
/// take(8usize),
-/// bytes::<_, _, Error<_>, _, _>(rest)
-/// )).parse_next(input)
+/// bytes::<_, _, InputError<_>, _, _>(rest)
+/// )).parse_peek(input)
/// }
///
/// let input = stream(&[0x12, 0x34, 0xff, 0xff]);
@@ -98,31 +101,36 @@ where
/// ```
pub fn bytes<I, O, E1, E2, P>(mut parser: P) -> impl Parser<(I, usize), O, E2>
where
- E1: ParseError<I> + ErrorConvert<E2>,
- E2: ParseError<(I, usize)>,
- I: Stream<Token = u8>,
+ E1: ParserError<I> + ErrorConvert<E2>,
+ E2: ParserError<(I, usize)>,
+ I: Stream<Token = u8> + Clone,
P: Parser<I, O, E1>,
{
- trace("bytes", move |(input, offset): (I, usize)| {
- let (inner, _) = if offset % 8 != 0 {
- input.next_slice(1 + offset / 8)
- } else {
- input.next_slice(offset / 8)
- };
- let i = (input, offset);
- match parser.parse_next(inner) {
- Ok((rest, res)) => Ok(((rest, 0), res)),
- Err(ErrMode::Incomplete(Needed::Unknown)) => Err(ErrMode::Incomplete(Needed::Unknown)),
- Err(ErrMode::Incomplete(Needed::Size(sz))) => Err(match sz.get().checked_mul(8) {
- Some(v) => ErrMode::Incomplete(Needed::new(v)),
- None => ErrMode::Cut(E2::assert(
- i,
- "overflow in turning needed bytes into needed bits",
- )),
- }),
- Err(e) => Err(e.convert()),
- }
- })
+ trace(
+ "bytes",
+ unpeek(move |(input, offset): (I, usize)| {
+ let (inner, _) = if offset % 8 != 0 {
+ input.peek_slice(1 + offset / 8)
+ } else {
+ input.peek_slice(offset / 8)
+ };
+ let i = (input, offset);
+ match parser.parse_peek(inner) {
+ Ok((rest, res)) => Ok(((rest, 0), res)),
+ Err(ErrMode::Incomplete(Needed::Unknown)) => {
+ Err(ErrMode::Incomplete(Needed::Unknown))
+ }
+ Err(ErrMode::Incomplete(Needed::Size(sz))) => Err(match sz.get().checked_mul(8) {
+ Some(v) => ErrMode::Incomplete(Needed::new(v)),
+ None => ErrMode::Cut(E2::assert(
+ &i,
+ "overflow in turning needed bytes into needed bits",
+ )),
+ }),
+ Err(e) => Err(e.convert()),
+ }
+ }),
+ )
}
/// Parse taking `count` bits
@@ -131,7 +139,7 @@ where
/// ```rust
/// # use winnow::prelude::*;
/// # use winnow::Bytes;
-/// # use winnow::error::{Error, ErrorKind};
+/// # use winnow::error::{InputError, ErrorKind};
/// use winnow::binary::bits::take;
///
/// type Stream<'i> = &'i Bytes;
@@ -141,7 +149,7 @@ where
/// }
///
/// fn parser(input: (Stream<'_>, usize), count: usize)-> IResult<(Stream<'_>, usize), u8> {
-/// take(count).parse_next(input)
+/// take(count).parse_peek(input)
/// }
///
/// // Consumes 0 bits, returns 0
@@ -154,32 +162,35 @@ where
/// assert_eq!(parser((stream(&[0b00010010]), 4), 4), Ok(((stream(&[]), 0), 0b00000010)));
///
/// // Tries to consume 12 bits but only 8 are available
-/// assert_eq!(parser((stream(&[0b00010010]), 0), 12), Err(winnow::error::ErrMode::Backtrack(Error{input: (stream(&[0b00010010]), 0), kind: ErrorKind::Eof })));
+/// assert_eq!(parser((stream(&[0b00010010]), 0), 12), Err(winnow::error::ErrMode::Backtrack(InputError::new((stream(&[0b00010010]), 0), ErrorKind::Eof))));
/// ```
#[inline(always)]
-pub fn take<I, O, C, E: ParseError<(I, usize)>>(count: C) -> impl Parser<(I, usize), O, E>
+pub fn take<I, O, C, E: ParserError<(I, usize)>>(count: C) -> impl Parser<(I, usize), O, E>
where
- I: Stream<Token = u8> + AsBytes + StreamIsPartial,
+ I: Stream<Token = u8> + AsBytes + StreamIsPartial + Clone,
C: ToUsize,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
{
let count = count.to_usize();
- trace("take", move |input: (I, usize)| {
- if <I as StreamIsPartial>::is_partial_supported() {
- take_::<_, _, _, true>(input, count)
- } else {
- take_::<_, _, _, false>(input, count)
- }
- })
+ trace(
+ "take",
+ unpeek(move |input: (I, usize)| {
+ if <I as StreamIsPartial>::is_partial_supported() {
+ take_::<_, _, _, true>(input, count)
+ } else {
+ take_::<_, _, _, false>(input, count)
+ }
+ }),
+ )
}
-fn take_<I, O, E: ParseError<(I, usize)>, const PARTIAL: bool>(
+fn take_<I, O, E: ParserError<(I, usize)>, const PARTIAL: bool>(
(input, bit_offset): (I, usize),
count: usize,
) -> IResult<(I, usize), O, E>
where
I: StreamIsPartial,
- I: Stream<Token = u8> + AsBytes,
+ I: Stream<Token = u8> + AsBytes + Clone,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
{
if count == 0 {
@@ -191,7 +202,7 @@ where
Err(ErrMode::Incomplete(Needed::new(count)))
} else {
Err(ErrMode::from_error_kind(
- (input, bit_offset),
+ &(input, bit_offset),
ErrorKind::Eof,
))
}
@@ -221,7 +232,7 @@ where
offset = 0;
}
}
- let (input, _) = input.next_slice(cnt);
+ let (input, _) = input.peek_slice(cnt);
Ok(((input, end_offset), acc))
}
}
@@ -234,7 +245,7 @@ where
/// ```rust
/// # use winnow::prelude::*;
/// # use winnow::Bytes;
-/// # use winnow::error::{Error, ErrorKind};
+/// # use winnow::error::{InputError, ErrorKind};
/// use winnow::binary::bits::tag;
///
/// type Stream<'i> = &'i Bytes;
@@ -247,7 +258,7 @@ where
/// /// Return Ok and the matching section of `input` if there's a match.
/// /// Return Err if there's no match.
/// fn parser(pattern: u8, count: u8, input: (Stream<'_>, usize)) -> IResult<(Stream<'_>, usize), u8> {
-/// tag(pattern, count).parse_next(input)
+/// tag(pattern, count).parse_peek(input)
/// }
///
/// // The lowest 4 bits of 0b00001111 match the lowest 4 bits of 0b11111111.
@@ -265,42 +276,46 @@ where
/// // The lowest 2 bits of 0b11111111 and 0b00000001 are different.
/// assert_eq!(
/// parser(0b000000_01, 2, (stream(&[0b111111_11]), 0)),
-/// Err(winnow::error::ErrMode::Backtrack(Error {
-/// input: (stream(&[0b11111111]), 0),
-/// kind: ErrorKind::Tag
-/// }))
+/// Err(winnow::error::ErrMode::Backtrack(InputError::new(
+/// (stream(&[0b11111111]), 0),
+/// ErrorKind::Tag
+/// )))
/// );
///
/// // The lowest 8 bits of 0b11111111 and 0b11111110 are different.
/// assert_eq!(
/// parser(0b11111110, 8, (stream(&[0b11111111]), 0)),
-/// Err(winnow::error::ErrMode::Backtrack(Error {
-/// input: (stream(&[0b11111111]), 0),
-/// kind: ErrorKind::Tag
-/// }))
+/// Err(winnow::error::ErrMode::Backtrack(InputError::new(
+/// (stream(&[0b11111111]), 0),
+/// ErrorKind::Tag
+/// )))
/// );
/// ```
#[inline(always)]
#[doc(alias = "literal")]
#[doc(alias = "just")]
-pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
+pub fn tag<I, O, C, E: ParserError<(I, usize)>>(
pattern: O,
count: C,
) -> impl Parser<(I, usize), O, E>
where
- I: Stream<Token = u8> + AsBytes + StreamIsPartial,
+ I: Stream<Token = u8> + AsBytes + StreamIsPartial + Clone,
C: ToUsize,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq,
{
let count = count.to_usize();
- trace("tag", move |input: (I, usize)| {
- let inp = input.clone();
+ trace("tag", move |input: &mut (I, usize)| {
+ let start = input.checkpoint();
- take(count).parse_next(input).and_then(|(i, o)| {
+ take(count).parse_next(input).and_then(|o| {
if pattern == o {
- Ok((i, o))
+ Ok(o)
} else {
- Err(ErrMode::Backtrack(E::from_error_kind(inp, ErrorKind::Tag)))
+ input.reset(start);
+ Err(ErrMode::Backtrack(E::from_error_kind(
+ input,
+ ErrorKind::Tag,
+ )))
}
})
})
@@ -313,7 +328,7 @@ where
/// ```rust
/// # use winnow::prelude::*;
/// # use winnow::Bytes;
-/// # use winnow::error::{Error, ErrorKind};
+/// # use winnow::error::{InputError, ErrorKind};
/// use winnow::binary::bits::bool;
///
/// type Stream<'i> = &'i Bytes;
@@ -323,20 +338,20 @@ where
/// }
///
/// fn parse(input: (Stream<'_>, usize)) -> IResult<(Stream<'_>, usize), bool> {
-/// bool.parse_next(input)
+/// bool.parse_peek(input)
/// }
///
/// assert_eq!(parse((stream(&[0b10000000]), 0)), Ok(((stream(&[0b10000000]), 1), true)));
/// assert_eq!(parse((stream(&[0b10000000]), 1)), Ok(((stream(&[0b10000000]), 2), false)));
/// ```
#[doc(alias = "any")]
-pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E>
+pub fn bool<I, E: ParserError<(I, usize)>>(input: &mut (I, usize)) -> PResult<bool, E>
where
- I: Stream<Token = u8> + AsBytes + StreamIsPartial,
+ I: Stream<Token = u8> + AsBytes + StreamIsPartial + Clone,
{
- trace("bool", |input: (I, usize)| {
- let (res, bit): (_, u32) = take(1usize).parse_next(input)?;
- Ok((res, bit != 0))
+ trace("bool", |input: &mut (I, usize)| {
+ let bit: u32 = take(1usize).parse_next(input)?;
+ Ok(bit != 0)
})
.parse_next(input)
}