Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1100
vendor/combine/src/error.rs vendored Normal file

File diff suppressed because it is too large Load Diff

29
vendor/combine/src/future_ext.rs vendored Normal file
View File

@@ -0,0 +1,29 @@
use crate::lib::future::Future;
use crate::lib::marker::Unpin;
use crate::lib::pin::Pin;
use crate::lib::task::{Context, Poll};
// Replace usage of this with std::future::poll_fn once it stabilizes
pub struct PollFn<F> {
f: F,
}
impl<F> Unpin for PollFn<F> {}
pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
PollFn { f }
}
impl<T, F> Future for PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
(&mut self.f)(cx)
}
}

1006
vendor/combine/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

661
vendor/combine/src/parser/byte.rs vendored Normal file
View File

@@ -0,0 +1,661 @@
//! Module containing parsers specialized on byte streams.
use crate::{
error::{self, ParseResult::*},
parser::{
combinator::no_partial,
range::{take_fn, TakeRange},
repeat::skip_many,
token::{satisfy, token, tokens_cmp, Token},
},
stream::{RangeStream, Stream},
Parser,
};
/// Parses a byte and succeeds if the byte is equal to `c`.
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::byte;
/// assert_eq!(byte(b'!').parse(&b"!"[..]), Ok((b'!', &b""[..])));
/// assert!(byte(b'A').parse(&b""[..]).is_err());
/// assert!(byte(b'A').parse(&b"!"[..]).is_err());
/// ```
pub fn byte<Input>(c: u8) -> Token<Input>
where
Input: Stream<Token = u8>,
{
token(c)
}
macro_rules! byte_parser {
($name:ident, $ty:ident, $f: ident) => {{
satisfy(|c: u8| c.$f())
.expected(stringify!($name))
}};
($name:ident, $ty:ident, $f: ident $($args:tt)+) => {{
satisfy(|c: u8| c.$f $($args)+)
.expected(stringify!($name))
}};
}
/// Parses a base-10 digit (09).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::digit;
/// assert_eq!(digit().parse(&b"9"[..]), Ok((b'9', &b""[..])));
/// assert!(digit().parse(&b"A"[..]).is_err());
/// ```
pub fn digit<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(digit, Digit, is_ascii_digit())
}
/// Parses a `b' '`, `b'\t'`, `b'\n'` or `'b\'r'`.
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::space;
/// assert_eq!(space().parse(&b" "[..]), Ok((b' ', &b""[..])));
/// assert_eq!(space().parse(&b" "[..]), Ok((b' ', &b" "[..])));
/// assert!(space().parse(&b"!"[..]).is_err());
/// assert!(space().parse(&b""[..]).is_err());
/// ```
pub fn space<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(space, Space, is_ascii_whitespace)
}
/// Skips over [`space`] zero or more times
///
/// [`space`]: fn.space.html
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::spaces;
/// assert_eq!(spaces().parse(&b""[..]), Ok(((), &b""[..])));
/// assert_eq!(spaces().parse(&b" "[..]), Ok(((), &b""[..])));
/// ```
pub fn spaces<Input>() -> impl Parser<Input, Output = ()>
where
Input: Stream<Token = u8>,
{
skip_many(space()).expected("whitespaces")
}
/// Parses a newline byte (`b'\n'`).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::newline;
/// assert_eq!(newline().parse(&b"\n"[..]), Ok((b'\n', &b""[..])));
/// assert!(newline().parse(&b"\r"[..]).is_err());
/// ```
pub fn newline<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
satisfy(|ch: u8| ch == b'\n').expected("lf newline")
}
/// Parses carriage return and newline (`&b"\r\n"`), returning the newline byte.
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::crlf;
/// assert_eq!(crlf().parse(&b"\r\n"[..]), Ok((b'\n', &b""[..])));
/// assert!(crlf().parse(&b"\r"[..]).is_err());
/// assert!(crlf().parse(&b"\n"[..]).is_err());
/// ```
pub fn crlf<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
no_partial(satisfy(|ch: u8| ch == b'\r').with(newline())).expected("crlf newline")
}
/// Parses a tab byte (`b'\t'`).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::tab;
/// assert_eq!(tab().parse(&b"\t"[..]), Ok((b'\t', &b""[..])));
/// assert!(tab().parse(&b" "[..]).is_err());
/// ```
pub fn tab<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
satisfy(|ch| ch == b'\t').expected("tab")
}
/// Parses an uppercase ASCII letter (AZ).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::upper;
/// assert_eq!(upper().parse(&b"A"[..]), Ok((b'A', &b""[..])));
/// assert!(upper().parse(&b"a"[..]).is_err());
/// ```
pub fn upper<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(upper, Upper, is_ascii_uppercase)
}
/// Parses an lowercase ASCII letter (az).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::lower;
/// assert_eq!(lower().parse(&b"a"[..]), Ok((b'a', &b""[..])));
/// assert!(lower().parse(&b"A"[..]).is_err());
/// ```
pub fn lower<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(lower, Lower, is_ascii_lowercase)
}
/// Parses either an ASCII alphabet letter or digit (az, AZ, 09).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::alpha_num;
/// assert_eq!(alpha_num().parse(&b"A"[..]), Ok((b'A', &b""[..])));
/// assert_eq!(alpha_num().parse(&b"1"[..]), Ok((b'1', &b""[..])));
/// assert!(alpha_num().parse(&b"!"[..]).is_err());
/// ```
pub fn alpha_num<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(alpha_num, AlphaNum, is_ascii_alphanumeric)
}
/// Parses an ASCII alphabet letter (az, AZ).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::letter;
/// assert_eq!(letter().parse(&b"a"[..]), Ok((b'a', &b""[..])));
/// assert_eq!(letter().parse(&b"A"[..]), Ok((b'A', &b""[..])));
/// assert!(letter().parse(&b"9"[..]).is_err());
/// ```
pub fn letter<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(letter, Letter, is_ascii_alphabetic)
}
/// Parses an octal digit.
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::oct_digit;
/// assert_eq!(oct_digit().parse(&b"7"[..]), Ok((b'7', &b""[..])));
/// assert!(oct_digit().parse(&b"8"[..]).is_err());
/// ```
pub fn oct_digit<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
satisfy(|ch| (b'0'..=b'7').contains(&ch)).expected("octal digit")
}
/// Parses an ASCII hexdecimal digit (accepts both uppercase and lowercase).
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::hex_digit;
/// assert_eq!(hex_digit().parse(&b"F"[..]), Ok((b'F', &b""[..])));
/// assert!(hex_digit().parse(&b"H"[..]).is_err());
/// ```
pub fn hex_digit<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
where
Input: Stream<Token = u8>,
{
byte_parser!(hex_digit, HexDigit, is_ascii_hexdigit())
}
parser! {
/// Parses the bytes `s`.
///
/// If you have a stream implementing [`RangeStream`] such as `&[u8]` you can also use the
/// [`range`] parser which may be more efficient.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::byte::bytes;
/// # fn main() {
/// let result = bytes(&b"rust"[..])
/// .parse(&b"rust"[..])
/// .map(|x| x.0);
/// assert_eq!(result, Ok(&b"rust"[..]));
/// # }
/// ```
///
/// [`RangeStream`]: super::super::stream::RangeStream
/// [`range`]: super::range::range
pub fn bytes['a, 'b, Input](s: &'static [u8])(Input) -> &'a [u8]
where [
Input: Stream<Token = u8, Range = &'b [u8]>,
]
{
bytes_cmp(s, |l: u8, r: u8| l == r)
}
}
parser! {
/// Parses the bytes `s` using `cmp` to compare each token.
///
/// If you have a stream implementing [`RangeStream`] such as `&[u8]` you can also use the
/// [`range`] parser which may be more efficient.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::byte::bytes_cmp;
/// # use combine::stream::easy::Info;
/// # fn main() {
/// let result = bytes_cmp(&b"abc"[..], |l, r| l.eq_ignore_ascii_case(&r))
/// .parse(&b"AbC"[..]);
/// assert_eq!(result, Ok((&b"abc"[..], &b""[..])));
/// # }
/// ```
///
/// [`RangeStream`]: super::super::stream::RangeStream
/// [`range`]: super::range::range
pub fn bytes_cmp['a, 'b, C, Input](s: &'static [u8], cmp: C)(Input) -> &'a [u8]
where [
C: FnMut(u8, u8) -> bool,
Input: Stream<Token = u8, Range = &'b [u8]>,
]
{
let s = *s;
tokens_cmp(s.iter().cloned(), cmp)
.map(move |_| s)
.expected(error::Range(s))
}
}
macro_rules! take_until {
(
$(#[$attr:meta])*
$type_name: ident, $func_name: ident, $memchr: ident, $($param: ident),+
) => {
parser!{
#[derive(Clone)]
pub struct $type_name;
type PartialState = usize;
$(#[$attr])*
pub fn $func_name[Input]($($param : u8),*)(Input) -> Input::Range
where [
Input: RangeStream,
Input::Range: AsRef<[u8]> + crate::stream::Range,
]
{
take_fn(move |haystack: Input::Range| {
let haystack = haystack.as_ref();
match ::memchr::$memchr( $(*$param),+ , haystack) {
Some(i) => TakeRange::Found(i),
None => TakeRange::NotFound(haystack.len()),
}
})
}
}
}
}
take_until! {
/// Zero-copy parser which reads a range of 0 or more tokens until `a` is found.
///
/// If `a` is not found, the parser will return an error.
///
/// ```
/// # extern crate combine;
/// # use combine::parser::byte::take_until_byte;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_until_byte(b'\r');
/// let result = parser.parse("To: user@example.com\r\n");
/// assert_eq!(result, Ok(("To: user@example.com", "\r\n")));
/// let result = parser.parse("Hello, world\n");
/// assert!(result.is_err());
/// # }
/// ```
TakeUntilByte, take_until_byte, memchr, a
}
take_until! {
/// Zero-copy parser which reads a range of 0 or more tokens until `a` or `b` is found.
///
/// If `a` or `b` is not found, the parser will return an error.
///
/// ```
/// # extern crate combine;
/// # use combine::parser::byte::take_until_byte2;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_until_byte2(b'\r', b'\n');
/// let result = parser.parse("To: user@example.com\r\n");
/// assert_eq!(result, Ok(("To: user@example.com", "\r\n")));
/// let result = parser.parse("Hello, world\n");
/// assert_eq!(result, Ok(("Hello, world", "\n")));
/// # }
/// ```
TakeUntilByte2, take_until_byte2, memchr2, a, b
}
take_until! {
/// Zero-copy parser which reads a range of 0 or more tokens until `a`, 'b' or `c` is found.
///
/// If `a`, 'b' or `c` is not found, the parser will return an error.
///
/// ```
/// # extern crate combine;
/// # use combine::parser::byte::take_until_byte3;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_until_byte3(b'\r', b'\n', b' ');
/// let result = parser.parse("To: user@example.com\r\n");
/// assert_eq!(result, Ok(("To:", " user@example.com\r\n")));
/// let result = parser.parse("Helloworld");
/// assert!(result.is_err());
/// # }
/// ```
TakeUntilByte3, take_until_byte3, memchr3, a, b, c
}
parser! {
type PartialState = usize;
/// Zero-copy parser which reads a range of 0 or more tokens until `needle` is found.
///
/// If `a`, 'b' or `c` is not found, the parser will return an error.
///
/// Optimized variant of [`take_until_range`](../range/fn.take_until_range.html)
///
/// ```
/// use combine::*;
/// use combine::parser::byte::take_until_bytes;
/// assert_eq!(
/// take_until_bytes(&b"\r\n"[..]).easy_parse(&b"abc\r\n"[..]).map(|(x, _)| x),
/// Ok((&b"abc"[..]))
/// );
/// // Also works on strings as long as `needle` is UTF-8
/// assert_eq!(
/// take_until_bytes("\r\n".as_bytes()).easy_parse("abc\r\n").map(|(x, _)| x),
/// Ok(("abc"))
/// );
/// ```
pub fn take_until_bytes['a, Input](needle: &'a [u8])(Input) -> Input::Range
where [
Input: RangeStream,
Input::Range: AsRef<[u8]> + crate::stream::Range,
]
{
take_fn(move |haystack: Input::Range| {
let haystack = haystack.as_ref();
match memslice(needle, haystack) {
Some(i) => TakeRange::Found(i),
None => TakeRange::NotFound(haystack.len().saturating_sub(needle.len() - 1)),
}
})
}
}
fn memslice(needle: &[u8], haystack: &[u8]) -> Option<usize> {
let (&prefix, suffix) = match needle.split_first() {
Some(x) => x,
None => return Some(0),
};
for i in memchr::memchr_iter(prefix, haystack) {
if haystack[i + 1..].starts_with(suffix) {
return Some(i);
}
}
None
}
/// Parsers for decoding numbers in big-endian or little-endian order.
pub mod num {
use crate::{error::ResultExt, lib::mem::size_of, parser::function::parser, stream::uncons};
use super::*;
macro_rules! integer_parser {
(
$(#[$attr:meta])*
pub $type_name: ident,
$output_type: ident, $be_name: ident, $le_name: ident, $read_name: ident
) => {
$(#[$attr])*
pub fn $be_name<'a, Input>() -> impl Parser<Input, Output = $output_type, PartialState = ()>
where
Input: Stream<Token = u8>,
{
parser(|input: &mut Input| {
let checkpoint = input.checkpoint();
let result = (|input: &mut Input| {
let mut buffer = [0u8; size_of::<$output_type>()];
for elem in &mut buffer[..] {
*elem = ctry!(uncons(input)).0;
}
CommitOk($output_type::from_be_bytes(buffer))
})(input);
if result.is_err() {
input.reset(checkpoint).committed().into_result()?;
}
result.into_result()
})
}
$(#[$attr])*
pub fn $le_name<'a, Input>() -> impl Parser<Input, Output = $output_type, PartialState = ()>
where
Input: Stream<Token = u8>,
{
parser(|input: &mut Input| {
let checkpoint = input.checkpoint();
let result = (|input: &mut Input| {
let mut buffer = [0u8; size_of::<$output_type>()];
for elem in &mut buffer[..] {
*elem = ctry!(uncons(input)).0;
}
CommitOk($output_type::from_le_bytes(buffer))
})(input);
if result.is_err() {
input.reset(checkpoint).committed().into_result()?;
}
result.into_result()
})
}
}
}
integer_parser!(
/// Reads a u16 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_u16;
///
/// assert_eq!(le_u16().parse(&b"\x01\0"[..]), Ok((1, &b""[..])));
/// assert!(le_u16().parse(&b"\0"[..]).is_err());
/// ```
pub U16, u16, be_u16, le_u16, read_u16
);
integer_parser!(
/// Reads a u32 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_u32;
///
/// assert_eq!(le_u32().parse(&b"\x01\0\0\0"[..]), Ok((1, &b""[..])));
/// assert!(le_u32().parse(&b"\x01\0\0"[..]).is_err());
/// ```
pub U32, u32, be_u32, le_u32, read_u32
);
integer_parser!(
/// Reads a u64 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_u64;
///
/// assert_eq!(le_u64().parse(&b"\x01\0\0\0\0\0\0\0"[..]), Ok((1, &b""[..])));
/// assert!(le_u64().parse(&b"\x01\0\0\0\0\0\0"[..]).is_err());
/// ```
pub U64, u64, be_u64, le_u64, read_u64
);
integer_parser!(
/// Reads a i16 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_i16;
///
/// assert_eq!(le_i16().parse(&b"\x01\0"[..]), Ok((1, &b""[..])));
/// assert!(le_i16().parse(&b"\x01"[..]).is_err());
/// ```
pub I16, i16, be_i16, le_i16, read_i16
);
integer_parser!(
/// Reads a i32 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_i32;
///
/// assert_eq!(le_i32().parse(&b"\x01\0\0\0"[..]), Ok((1, &b""[..])));
/// assert!(le_i32().parse(&b"\x01\0\0"[..]).is_err());
/// ```
pub I32, i32, be_i32, le_i32, read_i32
);
integer_parser!(
/// Reads a i64 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_i64;
///
/// assert_eq!(le_i64().parse(&b"\x01\0\0\0\0\0\0\0"[..]), Ok((1, &b""[..])));
/// assert!(le_i64().parse(&b"\x01\0\0\0\0\0\0"[..]).is_err());
/// ```
pub I64, i64, be_i64, le_i64, read_i64
);
integer_parser!(
/// Reads a i32 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_f32;
///
/// let buf = 123.45f32.to_le_bytes();
/// assert_eq!(le_f32().parse(&buf[..]), Ok((123.45, &b""[..])));
/// assert!(le_f32().parse(&b"\x01\0\0"[..]).is_err());
/// ```
pub F32, f32, be_f32, le_f32, read_f32
);
integer_parser!(
/// Reads a i64 out of the byte stream with the specified endianess
///
/// ```
/// use combine::Parser;
/// use combine::parser::byte::num::le_f64;
///
/// let buf = 123.45f64.to_le_bytes();
/// assert_eq!(le_f64().parse(&buf[..]), Ok((123.45, &b""[..])));
/// assert!(le_f64().parse(&b"\x01\0\0\0\0\0\0"[..]).is_err());
/// ```
pub F64, f64, be_f64, le_f64, read_f64
);
#[cfg(all(feature = "std", test))]
mod tests {
use crate::stream::{buffered, position, IteratorStream};
use super::*;
#[test]
fn no_rangestream() {
let buf = 123.45f64.to_le_bytes();
assert_eq!(
le_f64()
.parse(buffered::Stream::new(
position::Stream::new(IteratorStream::new(buf.iter().cloned())),
1
))
.map(|(t, _)| t),
Ok(123.45)
);
assert_eq!(
le_f64()
.parse(buffered::Stream::new(
position::Stream::new(IteratorStream::new(buf.iter().cloned())),
1
))
.map(|(t, _)| t),
Ok(123.45)
);
let buf = 123.45f64.to_be_bytes();
assert_eq!(
be_f64()
.parse(buffered::Stream::new(
position::Stream::new(IteratorStream::new(buf.iter().cloned())),
1
))
.map(|(t, _)| t),
Ok(123.45)
);
}
}
}
#[cfg(all(feature = "std", test))]
mod tests {
use crate::stream::{buffered, position, read};
use super::*;
#[test]
fn memslice_basic() {
let haystack = b"abc123";
assert_eq!(memslice(b"", haystack), Some(0));
assert_eq!(memslice(b"a", haystack), Some(0));
assert_eq!(memslice(b"ab", haystack), Some(0));
assert_eq!(memslice(b"c12", haystack), Some(2));
let haystack2 = b"abcab2";
assert_eq!(memslice(b"abc", haystack2), Some(0));
assert_eq!(memslice(b"ab2", haystack2), Some(3));
let haystack3 = b"aaabaaaa";
assert_eq!(memslice(b"aaaa", haystack3), Some(4));
}
#[test]
fn bytes_read_stream() {
assert!(bytes(b"abc")
.parse(buffered::Stream::new(
position::Stream::new(read::Stream::new("abc".as_bytes())),
1
))
.is_ok());
}
}

319
vendor/combine/src/parser/char.rs vendored Normal file
View File

@@ -0,0 +1,319 @@
//! Module containing parsers specialized on character streams.
use crate::{
parser::{
combinator::no_partial,
repeat::skip_many,
token::{satisfy, token, tokens_cmp, Token},
},
stream::Stream,
Parser,
};
/// Parses a character and succeeds if the character is equal to `c`.
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::char;
/// assert_eq!(char('!').parse("!"), Ok(('!', "")));
/// assert!(char('A').parse("!").is_err());
/// ```
pub fn char<Input>(c: char) -> Token<Input>
where
Input: Stream<Token = char>,
{
token(c)
}
parser! {
#[derive(Copy, Clone)]
pub struct Digit;
/// Parses a base-10 digit.
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::digit;
/// assert_eq!(digit().parse("9"), Ok(('9', "")));
/// assert!(digit().parse("A").is_err());
/// ```
pub fn digit[Input]()(Input) -> char
where
[Input: Stream<Token = char>,]
{
satisfy(|c: char| c.is_digit(10)).expected("digit")
}
}
/// Parse a single whitespace according to [`std::char::is_whitespace`].
///
/// This includes space characters, tabs and newlines.
///
/// [`std::char::is_whitespace`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_whitespace
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::space;
/// assert_eq!(space().parse(" "), Ok((' ', "")));
/// assert_eq!(space().parse(" "), Ok((' ', " ")));
/// assert!(space().parse("!").is_err());
/// assert!(space().parse("").is_err());
/// ```
pub fn space<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
let f: fn(char) -> bool = char::is_whitespace;
satisfy(f).expected("whitespace")
}
/// Skips over zero or more spaces according to [`std::char::is_whitespace`].
///
/// This includes space characters, tabs and newlines.
///
/// [`std::char::is_whitespace`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_whitespace
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::spaces;
/// assert_eq!(spaces().parse(""), Ok(((), "")));
/// assert_eq!(spaces().parse(" "), Ok(((), "")));
/// ```
pub fn spaces<Input>() -> impl Parser<Input, Output = ()>
where
Input: Stream<Token = char>,
{
skip_many(space()).expected("whitespaces")
}
/// Parses a newline character (`'\n'`).
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::newline;
/// assert_eq!(newline().parse("\n"), Ok(('\n', "")));
/// assert!(newline().parse("\r").is_err());
/// ```
pub fn newline<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch == '\n').expected("lf newline")
}
/// Parses carriage return and newline (`"\r\n"`), returning the newline character.
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::crlf;
/// assert_eq!(crlf().parse("\r\n"), Ok(('\n', "")));
/// assert!(crlf().parse("\r").is_err());
/// assert!(crlf().parse("\n").is_err());
/// ```
pub fn crlf<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
no_partial(satisfy(|ch: char| ch == '\r').with(newline())).expected("crlf newline")
}
/// Parses a tab character (`'\t'`).
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::tab;
/// assert_eq!(tab().parse("\t"), Ok(('\t', "")));
/// assert!(tab().parse(" ").is_err());
/// ```
pub fn tab<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch == '\t').expected("tab")
}
/// Parses an uppercase letter according to [`std::char::is_uppercase`].
///
/// [`std::char::is_uppercase`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_uppercase
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::upper;
/// assert_eq!(upper().parse("A"), Ok(('A', "")));
/// assert!(upper().parse("a").is_err());
/// ```
pub fn upper<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch.is_uppercase()).expected("uppercase letter")
}
/// Parses an lowercase letter according to [`std::char::is_lowercase`].
///
/// [`std::char::is_lowercase`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_lowercase
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::lower;
/// assert_eq!(lower().parse("a"), Ok(('a', "")));
/// assert!(lower().parse("A").is_err());
/// ```
pub fn lower<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch.is_lowercase()).expected("lowercase letter")
}
/// Parses either an alphabet letter or digit according to [`std::char::is_alphanumeric`].
///
/// [`std::char::is_alphanumeric`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_alphanumeric
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::alpha_num;
/// assert_eq!(alpha_num().parse("A"), Ok(('A', "")));
/// assert_eq!(alpha_num().parse("1"), Ok(('1', "")));
/// assert!(alpha_num().parse("!").is_err());
/// ```
pub fn alpha_num<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch.is_alphanumeric()).expected("letter or digit")
}
/// Parses an alphabet letter according to [`std::char::is_alphabetic`].
///
/// [`std::char::is_alphabetic`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_alphabetic
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::letter;
/// assert_eq!(letter().parse("a"), Ok(('a', "")));
/// assert_eq!(letter().parse("A"), Ok(('A', "")));
/// assert!(letter().parse("9").is_err());
/// ```
pub fn letter<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch.is_alphabetic()).expected("letter")
}
/// Parses an octal digit.
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::oct_digit;
/// assert_eq!(oct_digit().parse("7"), Ok(('7', "")));
/// assert!(oct_digit().parse("8").is_err());
/// ```
pub fn oct_digit<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch.is_digit(8)).expected("octal digit")
}
/// Parses a hexdecimal digit with uppercase and lowercase.
///
/// ```
/// use combine::Parser;
/// use combine::parser::char::hex_digit;
/// assert_eq!(hex_digit().parse("F"), Ok(('F', "")));
/// assert!(hex_digit().parse("H").is_err());
/// ```
pub fn hex_digit<Input>() -> impl Parser<Input, Output = char, PartialState = ()>
where
Input: Stream<Token = char>,
{
satisfy(|ch: char| ch.is_digit(0x10)).expected("hexadecimal digit")
}
/// Parses the string `s`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::string;
/// # fn main() {
/// let result = string("rust")
/// .parse("rust")
/// .map(|x| x.0);
/// assert_eq!(result, Ok("rust"));
/// # }
/// ```
pub fn string<'a, Input>(s: &'static str) -> impl Parser<Input, Output = &'a str>
where
Input: Stream<Token = char>,
{
string_cmp(s, |l, r| l == r)
}
/// Parses the string `s`, using `cmp` to compare each character.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::string_cmp;
/// # fn main() {
/// let result = string_cmp("rust", |l, r| l.eq_ignore_ascii_case(&r))
/// .parse("RusT")
/// .map(|x| x.0);
/// assert_eq!(result, Ok("rust"));
/// # }
/// ```
pub fn string_cmp<'a, C, Input>(s: &'static str, cmp: C) -> impl Parser<Input, Output = &'a str>
where
C: FnMut(char, char) -> bool,
Input: Stream<Token = char>,
{
tokens_cmp(s.chars(), cmp).map(move |_| s).expected(s)
}
#[cfg(all(feature = "std", test))]
mod tests {
use crate::{
parser::EasyParser,
stream::{
easy::{Error, Errors},
position::{self, SourcePosition},
},
};
use super::*;
#[test]
fn space_error() {
let result = space().easy_parse("");
assert!(result.is_err());
assert_eq!(
result.unwrap_err().errors,
vec![Error::end_of_input(), Error::Expected("whitespace".into())]
);
}
#[test]
fn string_committed() {
let result = string("a").easy_parse(position::Stream::new("b"));
assert!(result.is_err());
assert_eq!(
result.unwrap_err().position,
SourcePosition { line: 1, column: 1 }
);
}
#[test]
fn string_error() {
let result = string("abc").easy_parse(position::Stream::new("bc"));
assert_eq!(
result,
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![Error::Unexpected('b'.into()), Error::Expected("abc".into())],
})
);
}
}

849
vendor/combine/src/parser/choice.rs vendored Normal file
View File

@@ -0,0 +1,849 @@
//! Combinators which take one or more parsers and attempts to parse successfully with at least one
//! of them.
use crate::{
error::{
ParseError,
ParseResult::{self, *},
ResultExt, StreamError, Tracked,
},
parser::ParseMode,
ErrorOffset, Parser, Stream, StreamOnce,
};
/// Takes a number of parsers and tries to apply them each in order.
/// Fails if all the parsers fails or if an applied parser fails after it has committed to its
/// parse.
///
/// ```
/// # #[macro_use]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{digit, letter, string};
/// # use combine::stream::easy::Error;
/// # fn main() {
/// let mut parser = choice!(
/// many1(digit()),
/// string("let").map(|s| s.to_string()),
/// many1(letter()));
/// assert_eq!(parser.parse("let"), Ok(("let".to_string(), "")));
/// assert_eq!(parser.parse("123abc"), Ok(("123".to_string(), "abc")));
/// assert!(parser.parse(":123").is_err());
/// # }
/// ```
#[macro_export]
macro_rules! choice {
($first : expr) => {
$first
};
($first : expr, $($rest : expr),+) => {
$first.or(choice!($($rest),+))
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! parse_mode_choice {
(Input) => {
fn parse_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
self.parse_mode_choice($crate::parser::PartialMode::default(), input, state)
}
fn parse_first(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, Input::Error> {
self.parse_mode_choice($crate::parser::FirstMode, input, state)
}
};
}
/// `ChoiceParser` represents a parser which may parse one of several different choices depending
/// on the input.
///
/// This is an internal trait used to overload the `choice` function.
pub trait ChoiceParser<Input: Stream> {
type Output;
type PartialState: Default;
fn parse_first(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>;
fn parse_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>;
fn parse_mode_choice<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
Self: Sized;
fn add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>);
}
impl<'a, Input, P> ChoiceParser<Input> for &'a mut P
where
Input: Stream,
P: ?Sized + ChoiceParser<Input>,
{
type Output = P::Output;
type PartialState = P::PartialState;
parse_mode_choice!(Input);
#[inline]
fn parse_mode_choice<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
if mode.is_first() {
(**self).parse_first(input, state)
} else {
(**self).parse_partial(input, state)
}
}
fn add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
(**self).add_error_choice(error)
}
}
macro_rules! merge {
($head: ident) => {
$head.error
};
($head: ident $($tail: ident)+) => {
$head.error.merge(merge!($($tail)+))
};
}
macro_rules! do_choice {
(
$input: ident
$before_position: ident
$before: ident
$partial_state: ident
$state: ident
( )
$($parser: ident $error: ident)+
) => { {
let mut error = Tracked::from(merge!($($error)+));
// If offset != 1 then the nested parser is a sequence of parsers where 1 or
// more parsers returned `PeekOk` before the parser finally failed with
// `PeekErr`. Since we lose the offsets of the nested parsers when we merge
// the errors we must first extract the errors before we do the merge.
// If the offset == 0 on the other hand (which should be the common case) then
// we can delay the addition of the error since we know for certain that only
// the first parser in the sequence were tried
$(
if $error.offset != ErrorOffset(1) {
error.offset = $error.offset;
$parser.add_error(&mut error);
error.offset = ErrorOffset(0);
}
)+
PeekErr(error)
} };
(
$input: ident
$before_position: ident
$before: ident
$partial_state: ident
$state: ident
( $head: ident $($tail: ident)* )
$($all: ident)*
) => { {
let parser = $head;
let mut state = $head::PartialState::default();
match parser.parse_mode(crate::parser::FirstMode, $input, &mut state) {
CommitOk(x) => CommitOk(x),
PeekOk(x) => PeekOk(x),
CommitErr(err) => {
// If we get `CommitErr` but the input is the same this is a partial parse we
// cannot commit to so leave the state as `Peek` to retry all the parsers
// on the next call to `parse_partial`
if $input.position() != $before_position {
*$state = self::$partial_state::$head(state);
}
CommitErr(err)
}
PeekErr($head) => {
ctry!($input.reset($before.clone()).committed());
do_choice!(
$input
$before_position
$before
$partial_state
$state
( $($tail)* )
$($all)*
parser
$head
)
}
}
} }
}
macro_rules! tuple_choice_parser {
($head: ident) => {
tuple_choice_parser_inner!($head; $head);
};
($head: ident $($id: ident)+) => {
tuple_choice_parser_inner!($head; $head $($id)+);
tuple_choice_parser!($($id)+);
};
}
macro_rules! tuple_choice_parser_inner {
($partial_state: ident; $($id: ident)+) => {
#[doc(hidden)]
pub enum $partial_state<$($id),+> {
Peek,
$(
$id($id),
)+
}
impl<$($id),+> Default for self::$partial_state<$($id),+> {
fn default() -> Self {
self::$partial_state::Peek
}
}
#[allow(non_snake_case)]
impl<Input, Output $(,$id)+> ChoiceParser<Input> for ($($id,)+)
where
Input: Stream,
$($id: Parser< Input, Output = Output>),+
{
type Output = Output;
type PartialState = self::$partial_state<$($id::PartialState),+>;
parse_mode_choice!(Input);
#[inline]
fn parse_mode_choice<Mode>(
&mut self,
mode: Mode,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
Mode: ParseMode,
{
let ($(ref mut $id,)+) = *self;
let empty = match *state {
self::$partial_state::Peek => true,
_ => false,
};
if mode.is_first() || empty {
let before_position = input.position();
let before = input.checkpoint();
do_choice!(input before_position before $partial_state state ( $($id)+ ) )
} else {
match *state {
self::$partial_state::Peek => unreachable!(),
$(
self::$partial_state::$id(_) => {
let result = match *state {
self::$partial_state::$id(ref mut state) => {
$id.parse_mode(mode, input, state)
}
_ => unreachable!()
};
if result.is_ok() {
*state = self::$partial_state::Peek;
}
result
}
)+
}
}
}
fn add_error_choice(
&mut self,
error: &mut Tracked<<Input as StreamOnce>::Error>
) {
if error.offset != ErrorOffset(0) {
let ($(ref mut $id,)+) = *self;
// Reset the offset to 1 on every add so that we always (and only) takes the
// error of the first parser. If we don't do this the first parser will consume
// the offset to the detriment for all the other parsers.
$(
error.offset = ErrorOffset(1);
$id.add_error(error);
)+
}
}
}
}
}
tuple_choice_parser!(A B C D E F G H I J K L M N O P Q R S T U V X Y Z);
macro_rules! array_choice_parser {
($($t: tt)+) => {
$(
impl<Input, P> ChoiceParser<Input> for [P; $t]
where
Input: Stream,
P: Parser<Input>,
{
type Output = P::Output;
type PartialState = <[P] as ChoiceParser<Input>>::PartialState;
parse_mode_choice!(Input);
#[inline]
fn parse_mode_choice<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
if mode.is_first() {
self[..].parse_first(input, state)
} else {
self[..].parse_partial(input, state)
}
}
fn add_error_choice(
&mut self,
error: &mut Tracked<<Input as StreamOnce>::Error>
) {
self[..].add_error_choice(error)
}
}
)+
};
}
#[rustfmt::skip]
array_choice_parser!(
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
);
#[derive(Copy, Clone)]
pub struct Choice<P>(P);
impl<Input, P> Parser<Input> for Choice<P>
where
Input: Stream,
P: ChoiceParser<Input>,
{
type Output = P::Output;
type PartialState = P::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
self.0.parse_mode_choice(mode, input, state)
}
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
let before = error.offset.0;
self.0.add_error_choice(error);
error.offset.0 = before.saturating_sub(1);
}
}
fn slice_parse_mode<Input, P, M>(
self_: &mut [P],
mode: M,
input: &mut Input,
state: &mut (usize, P::PartialState),
) -> ParseResult<P::Output, <Input as StreamOnce>::Error>
where
P: Parser<Input>,
Input: Stream,
M: ParseMode,
{
let mut prev_err = None;
let mut last_parser_having_non_1_offset = 0;
let before = input.checkpoint();
let (ref mut index_state, ref mut child_state) = *state;
if !mode.is_first() && *index_state != 0 {
return self_[*index_state - 1]
.parse_partial(input, child_state)
.map(|x| {
*index_state = 0;
x
});
}
for i in 0..self_.len() {
ctry!(input.reset(before.clone()).committed());
match self_[i].parse_mode(mode, input, child_state) {
committed_err @ CommitErr(_) => {
*index_state = i + 1;
return committed_err;
}
PeekErr(err) => {
prev_err = match prev_err {
None => Some(err),
Some(mut prev_err) => {
if prev_err.offset != ErrorOffset(1) {
// First add the errors of all the preceding parsers which did not
// have a sequence of parsers returning `PeekOk` before failing
// with `PeekErr`.
let offset = prev_err.offset;
for p in &mut self_[last_parser_having_non_1_offset..(i - 1)] {
prev_err.offset = ErrorOffset(1);
p.add_error(&mut prev_err);
}
// Then add the errors if the current parser
prev_err.offset = offset;
self_[i - 1].add_error(&mut prev_err);
last_parser_having_non_1_offset = i;
}
Some(Tracked {
error: prev_err.error.merge(err.error),
offset: err.offset,
})
}
};
}
ok @ CommitOk(_) | ok @ PeekOk(_) => {
*index_state = 0;
return ok;
}
}
}
PeekErr(match prev_err {
None => Input::Error::from_error(
input.position(),
StreamError::message_static_message("parser choice is empty"),
)
.into(),
Some(mut prev_err) => {
if prev_err.offset != ErrorOffset(1) {
let offset = prev_err.offset;
let len = self_.len();
for p in &mut self_[last_parser_having_non_1_offset..(len - 1)] {
prev_err.offset = ErrorOffset(1);
p.add_error(&mut prev_err);
}
prev_err.offset = offset;
self_.last_mut().unwrap().add_error(&mut prev_err);
prev_err.offset = ErrorOffset(0);
}
prev_err
}
})
}
impl<Input, O, P> ChoiceParser<Input> for [P]
where
Input: Stream,
P: Parser<Input, Output = O>,
{
type Output = O;
type PartialState = (usize, P::PartialState);
#[inline]
fn parse_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
slice_parse_mode(self, crate::parser::PartialMode::default(), input, state)
}
#[inline]
fn parse_first(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
slice_parse_mode(self, crate::parser::FirstMode, input, state)
}
#[inline]
fn parse_mode_choice<M>(
&mut self,
_mode: M,
_input: &mut Input,
_state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
unreachable!()
}
fn add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
if error.offset != ErrorOffset(0) {
for p in self {
error.offset = ErrorOffset(1);
p.add_error(error);
}
}
}
}
/// Takes a tuple, a slice or an array of parsers and tries to apply them each in order.
/// Fails if all the parsers fails or if an applied parser consumes input before failing.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::{digit, string};
/// # fn main() {
/// // `choice` is overloaded on tuples so that different types of parsers can be used
/// // (each parser must still have the same input and output types)
/// let mut parser = choice((
/// string("Apple").map(|s| s.to_string()),
/// many1(digit()),
/// string("Orange").map(|s| s.to_string()),
/// ));
/// assert_eq!(parser.parse("1234"), Ok(("1234".to_string(), "")));
/// assert_eq!(parser.parse("Orangexx"), Ok(("Orange".to_string(), "xx")));
/// assert!(parser.parse("Appl").is_err());
/// assert!(parser.parse("Pear").is_err());
///
/// // If arrays or slices are used then all parsers must have the same type
/// // (`string` in this case)
/// let mut parser2 = choice([string("one"), string("two"), string("three")]);
/// // Fails as the parser for "two" consumes the first 't' before failing
/// assert!(parser2.parse("three").is_err());
///
/// // Use 'attempt' to make failing parsers always act as if they have not committed any input
/// let mut parser3 = choice([attempt(string("one")), attempt(string("two")), attempt(string("three"))]);
/// assert_eq!(parser3.parse("three"), Ok(("three", "")));
/// # }
/// ```
pub fn choice<Input, P>(ps: P) -> Choice<P>
where
Input: Stream,
P: ChoiceParser<Input>,
{
Choice(ps)
}
#[derive(Copy, Clone)]
pub struct Or<P1, P2>(Choice<(P1, P2)>);
impl<Input, O, P1, P2> Parser<Input> for Or<P1, P2>
where
Input: Stream,
P1: Parser<Input, Output = O>,
P2: Parser<Input, Output = O>,
{
type Output = O;
type PartialState = <Choice<(P1, P2)> as Parser<Input>>::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
self.0.parse_mode(mode, input, state)
}
#[inline]
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
if errors.offset != ErrorOffset(0) {
self.0.add_error(errors);
}
}
}
/// Equivalent to [`p1.or(p2)`].
///
/// If you are looking to chain 3 or more parsers using `or` you may consider using the
/// [`choice!`] macro instead, which can be clearer and may result in a faster parser.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::choice::or;
/// # use combine::parser::char::{digit, string};
/// # fn main() {
/// let mut parser = or(
/// string("let"),
/// or(digit().map(|_| "digit"), string("led")),
/// );
/// assert_eq!(parser.parse("let"), Ok(("let", "")));
/// assert_eq!(parser.parse("1"), Ok(("digit", "")));
/// assert!(parser.parse("led").is_err());
///
/// let mut parser2 = or(string("two"), string("three"));
/// // Fails as the parser for "two" consumes the first 't' before failing
/// assert!(parser2.parse("three").is_err());
///
/// // Use 'attempt' to make failing parsers always act as if they have not committed any input
/// let mut parser3 = or(attempt(string("two")), attempt(string("three")));
/// assert_eq!(parser3.parse("three"), Ok(("three", "")));
/// # }
/// ```
///
/// [`choice!`]: ../../macro.choice.html
/// [`p1.or(p2)`]: ../trait.Parser.html#method.or
pub fn or<Input, P1, P2>(p1: P1, p2: P2) -> Or<P1, P2>
where
Input: Stream,
P1: Parser<Input>,
P2: Parser<Input, Output = P1::Output>,
{
Or(choice((p1, p2)))
}
#[derive(Copy, Clone)]
pub struct Optional<P>(P);
impl<Input, P> Parser<Input> for Optional<P>
where
Input: Stream,
P: Parser<Input>,
{
type Output = Option<P::Output>;
type PartialState = P::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
let before = input.checkpoint();
match self.0.parse_mode(mode, input, state) {
PeekOk(x) => PeekOk(Some(x)),
CommitOk(x) => CommitOk(Some(x)),
CommitErr(err) => CommitErr(err),
PeekErr(_) => {
ctry!(input.reset(before).committed());
PeekOk(None)
}
}
}
forward_parser!(Input, add_error parser_count, 0);
}
/// Parses `parser` and outputs `Some(value)` if it succeeds, `None` if it fails without
/// consuming any input. Fails if `parser` fails after having committed some input.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::string;
/// # fn main() {
/// let mut parser = optional(string("hello"));
/// assert_eq!(parser.parse("hello"), Ok((Some("hello"), "")));
/// assert_eq!(parser.parse("world"), Ok((None, "world")));
/// assert!(parser.parse("heya").is_err());
/// # }
/// ```
pub fn optional<Input, P>(parser: P) -> Optional<P>
where
Input: Stream,
P: Parser<Input>,
{
Optional(parser)
}
#[macro_export]
#[doc(hidden)]
macro_rules! parse_mode_dispatch {
() => {
fn parse_partial(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
self.parse_mode_dispatch($crate::parser::PartialMode::default(), input, state)
}
fn parse_first(
&mut self,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
self.parse_mode_dispatch($crate::parser::FirstMode, input, state)
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! dispatch_parser_impl {
($parser_name: ident [$first_ident: ident $($id: ident)*] [$($collected_idents: ident)*] $expr: expr, $($rest: expr,)*) => {
$crate::dispatch_parser_impl!{ $parser_name [ $($id)* ] [$($collected_idents)* $first_ident] $($rest,)*}
};
($parser_name: ident [$($id: ident)*] [$($collected_idents: ident)*]) => {
$crate::dispatch_parser_impl!{ $parser_name; $($collected_idents)* }
};
($parser_name: ident; $($id: ident)*) => {
pub enum $parser_name<$($id),*> {
$(
$id($id),
)*
}
#[allow(non_snake_case)]
impl<Input, Output, $($id),*> $crate::Parser<Input> for $parser_name<$($id),*>
where
$( $id: $crate::Parser<Input, Output = Output>, )*
Input: $crate::Stream,
{
type Output = Output;
type PartialState = Option<$parser_name<$($id::PartialState),*>>;
$crate::parse_mode!(Input);
fn parse_mode<Mode>(
&mut self,
mode: Mode,
input: &mut Input,
state: &mut Self::PartialState,
) -> $crate::error::ParseResult<Self::Output, <Input as $crate::StreamOnce>::Error>
where
Mode: $crate::parser::ParseMode,
{
match self {
$(
$parser_name::$id($id) => {
let state = match state {
Some($parser_name::$id(s)) => s,
_ => {
*state = Some($parser_name::$id(Default::default()));
match state {
Some($parser_name::$id(s)) => s,
_ => unreachable!(),
}
}
};
$id.parse_mode(mode, input, state)
}
)*
}
}
fn add_error(&mut self, error: &mut $crate::error::Tracked<<Input as $crate::StreamOnce>::Error>) {
match self {
$(
$parser_name::$id($id) => $id.add_error(error),
)*
}
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! dispatch_inner {
($expr_ident: ident [$first_ident: ident $($id: ident)*] [$($collected: tt)*] $($pat: pat)|+ $(if $pred:expr)? => $expr: expr, $($rest_alt: tt)*) => {
$crate::dispatch_inner!{ $expr_ident [ $($id)* ] [$($collected)* $first_ident $($pat)|+ $(if $pred)? => $expr,] $($rest_alt)*}
};
($expr_ident: ident [$($id: ident)*] [$($collected: tt)*]) => {
$crate::dispatch_inner!{ $expr_ident $($collected)* }
};
($expr_ident: ident [$($ident_tt: tt)*]) => {
unreachable!()
};
($expr_ident: ident $( $ident: ident $($pat: pat)|+ $(if $pred:expr)? => $expr: expr,)+ ) => {
match $expr_ident {
$(
$($pat)|+ $(if $pred)? => Dispatch::$ident(check_parser($expr)),
)+
}
}
}
/// `dispatch!` allows a parser to be constructed depending on earlier input, without forcing each
/// branch to have the same type of parser
///
/// ```
/// use combine::{dispatch, any, token, satisfy, EasyParser, Parser};
///
/// let mut parser = any().then(|e| {
/// dispatch!(e;
/// 'a' => token('a'),
/// 'b' => satisfy(|b| b == 'b'),
/// t if t == 'c' => any(),
/// _ => token('d')
/// )
/// });
/// assert_eq!(parser.easy_parse("aa"), Ok(('a', "")));
/// assert_eq!(parser.easy_parse("cc"), Ok(('c', "")));
/// assert_eq!(parser.easy_parse("cd"), Ok(('d', "")));
/// assert!(parser.easy_parse("ab").is_err());
/// ```
#[macro_export]
macro_rules! dispatch {
($match_expr: expr; $( $($pat: pat)|+ $(if $pred:expr)? => $expr: expr ),+ $(,)? ) => {
{
$crate::dispatch_parser_impl!{ Dispatch [A B C D E F G H I J K L M N O P Q R S T U V X Y Z] [] $($expr,)+ }
fn check_parser<Input, P>(p: P) -> P where P: $crate::Parser<Input>, Input: $crate::Stream { p }
let e = $match_expr;
let parser = $crate::dispatch_inner!(e [A B C D E F G H I J K L M N O P Q R S T U V X Y Z] []
$(
$($pat)|+ $(if $pred)? => $expr,
)*
);
parser
}
}
}
#[cfg(all(feature = "std", test))]
mod tests {
use crate::parser::{token::any, EasyParser};
use super::*;
#[test]
fn choice_single_parser() {
assert!(choice((any(),),).easy_parse("a").is_ok());
}
}

1558
vendor/combine/src/parser/combinator.rs vendored Normal file

File diff suppressed because it is too large Load Diff

245
vendor/combine/src/parser/error.rs vendored Normal file
View File

@@ -0,0 +1,245 @@
//! Parsers which cause errors or modifies the returned error on parse failure.
use crate::{
error::{
ErrorInfo, ParseError,
ParseResult::{self, *},
StreamError, Tracked,
},
lib::marker::PhantomData,
parser::ParseMode,
Parser, Stream, StreamOnce,
};
#[derive(Clone)]
pub struct Unexpected<I, T, E>(E, PhantomData<fn(I) -> (I, T)>)
where
I: Stream;
impl<Input, T, E> Parser<Input> for Unexpected<Input, T, E>
where
Input: Stream,
E: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, <Input as StreamOnce>::Error> {
PeekErr(<Input as StreamOnce>::Error::empty(input.position()).into())
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
errors.error.add(StreamError::unexpected(&self.0));
}
}
/// Always fails with `message` as an unexpected error.
/// Never consumes any input.
///
/// Has `()` the output type
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::error::StreamError;
/// # fn main() {
/// let result = unexpected("token")
/// .easy_parse("a");
/// assert!(result.is_err());
/// assert!(
/// result.err()
/// .unwrap()
/// .errors
/// .iter()
/// .any(|m| *m == StreamError::unexpected("token"))
/// );
/// # }
/// ```
pub fn unexpected<Input, S>(message: S) -> Unexpected<Input, (), S>
where
Input: Stream,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
unexpected_any(message)
}
/// Always fails with `message` as an unexpected error.
/// Never consumes any input.
///
/// May have anything as the output type but must be used such that the output type can inferred.
/// The `unexpected` parser can be used if the output type does not matter
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::error::unexpected_any;
/// # use combine::error::StreamError;
/// # fn main() {
/// let result = token('b').or(unexpected_any("token"))
/// .easy_parse("a");
/// assert!(result.is_err());
/// assert!(
/// result.err()
/// .unwrap()
/// .errors
/// .iter()
/// .any(|m| *m == StreamError::unexpected("token"))
/// );
/// # }
/// ```
pub fn unexpected_any<Input, S, T>(message: S) -> Unexpected<Input, T, S>
where
Input: Stream,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
Unexpected(message, PhantomData)
}
#[derive(Clone)]
pub struct Message<P, S>(P, S);
impl<Input, P, S> Parser<Input> for Message<P, S>
where
Input: Stream,
P: Parser<Input>,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
type Output = P::Output;
type PartialState = P::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
match self.0.parse_mode(mode, input, state) {
CommitOk(x) => CommitOk(x),
PeekOk(x) => PeekOk(x),
// The message should always be added even if some input was committed before failing
CommitErr(mut err) => {
err.add_message(&self.1);
CommitErr(err)
}
// The message will be added in `add_error`
PeekErr(err) => PeekErr(err),
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
self.0.add_error(errors);
errors.error.add_message(&self.1);
}
forward_parser!(Input, parser_count add_committed_expected_error, 0);
}
/// Equivalent to [`p1.message(msg)`].
///
/// [`p1.message(msg)`]: ../trait.Parser.html#method.message
pub fn message<Input, P, S>(p: P, msg: S) -> Message<P, S>
where
P: Parser<Input>,
Input: Stream,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
Message(p, msg)
}
#[derive(Clone)]
pub struct Expected<P, S>(P, S);
impl<Input, P, S> Parser<Input> for Expected<P, S>
where
P: Parser<Input>,
Input: Stream,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
type Output = P::Output;
type PartialState = P::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
self.0.parse_mode(mode, input, state)
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
ParseError::set_expected(errors, StreamError::expected(&self.1), |errors| {
self.0.add_error(errors);
})
}
forward_parser!(Input, parser_count add_committed_expected_error, 0);
}
/// Equivalent to [`p.expected(info)`].
///
/// [`p.expected(info)`]: ../trait.Parser.html#method.expected
pub fn expected<Input, P, S>(p: P, info: S) -> Expected<P, S>
where
P: Parser<Input>,
Input: Stream,
S: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
{
Expected(p, info)
}
#[derive(Clone)]
pub struct Silent<P>(P);
impl<Input, P> Parser<Input> for Silent<P>
where
P: Parser<Input>,
Input: Stream,
{
type Output = P::Output;
type PartialState = P::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
self.0.parse_mode(mode, input, state).map_err(|mut err| {
err.clear_expected();
err
})
}
fn add_error(&mut self, _errors: &mut Tracked<<Input as StreamOnce>::Error>) {}
fn add_committed_expected_error(
&mut self,
_errors: &mut Tracked<<Input as StreamOnce>::Error>,
) {
}
forward_parser!(Input, parser_count, 0);
}
/// Equivalent to [`p.silent()`].
///
/// [`p.silent()`]: ../trait.Parser.html#method.silent
pub fn silent<Input, P>(p: P) -> Silent<P>
where
P: Parser<Input>,
Input: Stream,
{
Silent(p)
}

178
vendor/combine/src/parser/function.rs vendored Normal file
View File

@@ -0,0 +1,178 @@
//! Parsers constructor from regular functions
use crate::{
error::{ParseResult, StdParseResult},
lib::marker::PhantomData,
stream::Stream,
Parser,
};
impl<'a, Input: Stream, O> Parser<Input>
for dyn FnMut(&mut Input) -> StdParseResult<O, Input> + 'a
{
type Output = O;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
self(input).into()
}
}
#[derive(Copy, Clone)]
pub struct FnParser<Input, F>(F, PhantomData<fn(Input) -> Input>);
/// Wraps a function, turning it into a parser.
///
/// Mainly needed to turn closures into parsers as function types can be casted to function pointers
/// to make them usable as a parser.
///
/// ```
/// extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::digit;
/// # use combine::error::{Commit, StreamError};
/// # use combine::stream::easy;
/// # fn main() {
/// let mut even_digit = parser(|input| {
/// // Help type inference out
/// let _: &mut easy::Stream<&str> = input;
/// let position = input.position();
/// let (char_digit, committed) = digit().parse_stream(input).into_result()?;
/// let d = (char_digit as i32) - ('0' as i32);
/// if d % 2 == 0 {
/// Ok((d, committed))
/// }
/// else {
/// //Return an empty error since we only tested the first token of the stream
/// let errors = easy::Errors::new(
/// position,
/// StreamError::expected("even number")
/// );
/// Err(Commit::Peek(errors.into()))
/// }
/// });
/// let result = even_digit
/// .easy_parse("8")
/// .map(|x| x.0);
/// assert_eq!(result, Ok(8));
/// # }
/// ```
pub fn parser<Input, O, F>(f: F) -> FnParser<Input, F>
where
Input: Stream,
F: FnMut(&mut Input) -> StdParseResult<O, Input>,
{
FnParser(f, PhantomData)
}
impl<Input, O, F> Parser<Input> for FnParser<Input, F>
where
Input: Stream,
F: FnMut(&mut Input) -> StdParseResult<O, Input>,
{
type Output = O;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
(self.0)(input).into()
}
}
impl<Input, O> Parser<Input> for fn(&mut Input) -> StdParseResult<O, Input>
where
Input: Stream,
{
type Output = O;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
self(input).into()
}
}
#[derive(Copy)]
pub struct EnvParser<E, Input, T>
where
Input: Stream,
{
env: E,
parser: fn(E, &mut Input) -> StdParseResult<T, Input>,
}
impl<E, Input, T> Clone for EnvParser<E, Input, T>
where
Input: Stream,
E: Clone,
{
fn clone(&self) -> Self {
EnvParser {
env: self.env.clone(),
parser: self.parser,
}
}
}
impl<Input, E, O> Parser<Input> for EnvParser<E, Input, O>
where
E: Clone,
Input: Stream,
{
type Output = O;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<O, Input::Error> {
(self.parser)(self.env.clone(), input).into()
}
}
/// Constructs a parser out of an environment and a function which needs the given environment to
/// do the parsing. This is commonly useful to allow multiple parsers to share some environment
/// while still allowing the parsers to be written in separate functions.
///
/// ```
/// # extern crate combine;
/// # use std::collections::HashMap;
/// # use combine::*;
/// # use combine::parser::function::env_parser;
/// # use combine::parser::char::letter;
/// # fn main() {
/// struct Interner(HashMap<String, u32>);
/// impl Interner {
/// fn string<Input>(&self, input: &mut Input) -> StdParseResult<u32, Input>
/// where Input: Stream<Token = char>,
/// {
/// many(letter())
/// .map(|s: String| self.0.get(&s).cloned().unwrap_or(0))
/// .parse_stream(input)
/// .into_result()
/// }
/// }
///
/// let mut map = HashMap::new();
/// map.insert("hello".into(), 1);
/// map.insert("test".into(), 2);
///
/// let env = Interner(map);
/// let mut parser = env_parser(&env, Interner::string);
///
/// let result = parser.parse("hello");
/// assert_eq!(result, Ok((1, "")));
///
/// let result = parser.parse("world");
/// assert_eq!(result, Ok((0, "")));
/// # }
/// ```
pub fn env_parser<E, Input, O>(
env: E,
parser: fn(E, &mut Input) -> StdParseResult<O, Input>,
) -> EnvParser<E, Input, O>
where
E: Clone,
Input: Stream,
{
EnvParser { env, parser }
}

1207
vendor/combine/src/parser/mod.rs vendored Normal file

File diff suppressed because it is too large Load Diff

767
vendor/combine/src/parser/range.rs vendored Normal file
View File

@@ -0,0 +1,767 @@
//! Module containing zero-copy parsers.
//!
//! These parsers require the [`RangeStream`][] bound instead of a plain [`Stream`][].
//!
//! [`RangeStream`]: ../../stream/trait.RangeStream.html
//! [`Stream`]: ../../stream/trait.Stream.html
use crate::{
error::{
self, ParseError,
ParseResult::{self, *},
ResultExt, StreamError, Tracked,
},
lib::{convert::TryFrom, marker::PhantomData},
parser::ParseMode,
};
#[cfg(feature = "std")]
use crate::lib::error::Error as StdError;
#[cfg(not(feature = "std"))]
use crate::lib::fmt;
use crate::stream::{
uncons_range, uncons_while, uncons_while1, wrap_stream_error, Range as StreamRange,
RangeStream, StreamErrorFor, StreamOnce,
};
use crate::Parser;
pub struct Range<Input>(Input::Range)
where
Input: RangeStream;
impl<Input> Parser<Input> for Range<Input>
where
Input: RangeStream,
Input::Range: PartialEq + crate::stream::Range,
{
type Output = Input::Range;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
use crate::stream::Range;
let position = input.position();
match input.uncons_range(self.0.len()) {
Ok(other) => {
if other == self.0 {
CommitOk(other)
} else {
PeekErr(Input::Error::empty(position).into())
}
}
Err(err) => wrap_stream_error(input, err),
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
// TODO Add unexpected message?
errors.error.add_expected(error::Range(self.0.clone()));
}
}
parser! {
#[derive(Clone)]
pub struct Recognize;
type PartialState = <RecognizeWithValue<P> as Parser<Input>>::PartialState;
/// Zero-copy parser which returns committed input range.
///
/// [`combinator::recognize`][] is a non-`RangeStream` alternative.
///
/// [`combinator::recognize`]: ../../parser/combinator/fn.recognize.html
/// ```
/// # extern crate combine;
/// # use combine::parser::range::recognize;
/// # use combine::parser::char::letter;
/// # use combine::*;
/// # fn main() {
/// let mut parser = recognize(skip_many1(letter()));
/// assert_eq!(parser.parse("hello world"), Ok(("hello", " world")));
/// assert!(parser.parse("!").is_err());
/// # }
/// ```
pub fn recognize[Input, P](parser: P)(Input) -> <Input as StreamOnce>::Range
where [
P: Parser<Input>,
Input: RangeStream,
<Input as StreamOnce>::Range: crate::stream::Range,
]
{
recognize_with_value(parser).map(|(range, _)| range)
}
}
#[inline]
fn parse_partial_range<M, F, G, S, Input>(
mode: M,
input: &mut Input,
distance_state: &mut usize,
state: S,
first: F,
resume: G,
) -> ParseResult<Input::Range, Input::Error>
where
M: ParseMode,
F: FnOnce(&mut Input, S) -> ParseResult<Input::Range, <Input as StreamOnce>::Error>,
G: FnOnce(&mut Input, S) -> ParseResult<Input::Range, <Input as StreamOnce>::Error>,
Input: RangeStream,
{
let before = input.checkpoint();
if !input.is_partial() {
first(input, state)
} else if mode.is_first() || *distance_state == 0 {
let result = first(input, state);
if let CommitErr(_) = result {
*distance_state = input.distance(&before);
ctry!(input.reset(before).committed());
}
result
} else {
if input.uncons_range(*distance_state).is_err() {
panic!("recognize errored when restoring the input stream to its expected state");
}
match resume(input, state) {
CommitOk(_) | PeekOk(_) => (),
PeekErr(err) => return PeekErr(err),
CommitErr(err) => {
*distance_state = input.distance(&before);
ctry!(input.reset(before).committed());
return CommitErr(err);
}
}
let distance = input.distance(&before);
ctry!(input.reset(before).committed());
take(distance).parse_lazy(input).map(|range| {
*distance_state = 0;
range
})
}
}
#[derive(Clone)]
pub struct RecognizeWithValue<P>(P);
impl<Input, P> Parser<Input> for RecognizeWithValue<P>
where
P: Parser<Input>,
Input: RangeStream,
<Input as StreamOnce>::Range: crate::stream::Range,
{
type Output = (<Input as StreamOnce>::Range, P::Output);
type PartialState = (usize, P::PartialState);
parse_mode!(Input);
#[inline]
fn parse_mode<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
let (ref mut distance_state, ref mut child_state) = *state;
let before = input.checkpoint();
if !mode.is_first() && input.uncons_range(*distance_state).is_err() {
panic!("recognize errored when restoring the input stream to its expected state");
}
let value = match self.0.parse_mode(mode, input, child_state) {
CommitOk(x) | PeekOk(x) => x,
PeekErr(err) => return PeekErr(err),
CommitErr(err) => {
*distance_state = input.distance(&before);
ctry!(input.reset(before).committed());
return CommitErr(err);
}
};
let distance = input.distance(&before);
ctry!(input.reset(before).committed());
take(distance).parse_lazy(input).map(|range| {
*distance_state = 0;
(range, value)
})
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
self.0.add_error(errors)
}
}
/// Zero-copy parser which returns a pair: (committed input range, parsed value).
///
///
/// [`combinator::recognize_with_value`] is a non-`RangeStream` alternative.
///
/// [`combinator::recognize_with_value`]: recognize_with_value
/// ```
/// # extern crate combine;
/// # use combine::parser::range::recognize_with_value;
/// # use combine::parser::char::{digit, char};
/// # use combine::*;
/// # fn main() {
/// let mut parser = recognize_with_value((
/// skip_many1(digit()),
/// optional((attempt(char('.')), skip_many1(digit()))),
/// ).map(|(_, opt)| opt.is_some()));
///
/// assert_eq!(parser.parse("1234!"), Ok((("1234", false), "!")));
/// assert_eq!(parser.parse("1234.0001!"), Ok((("1234.0001", true), "!")));
/// assert!(parser.parse("!").is_err());
/// assert!(parser.parse("1234.").is_err());
/// # }
/// ```
pub fn recognize_with_value<Input, P>(parser: P) -> RecognizeWithValue<P>
where
P: Parser<Input>,
Input: RangeStream,
<Input as StreamOnce>::Range: crate::stream::Range,
{
RecognizeWithValue(parser)
}
/// Zero-copy parser which reads a range of length `i.len()` and succeeds if `i` is equal to that
/// range.
///
/// [`tokens`] is a non-`RangeStream` alternative.
///
/// [`tokens`]: super::token::tokens
/// ```
/// # extern crate combine;
/// # use combine::parser::range::range;
/// # use combine::*;
/// # fn main() {
/// let mut parser = range("hello");
/// let result = parser.parse("hello world");
/// assert_eq!(result, Ok(("hello", " world")));
/// let result = parser.parse("hel world");
/// assert!(result.is_err());
/// # }
/// ```
pub fn range<Input>(i: Input::Range) -> Range<Input>
where
Input: RangeStream,
Input::Range: PartialEq,
{
Range(i)
}
pub struct Take<Input>(usize, PhantomData<fn(Input)>);
impl<Input> Parser<Input> for Take<Input>
where
Input: RangeStream,
{
type Output = Input::Range;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
uncons_range(input, self.0)
}
}
/// Zero-copy parser which reads a range of length `n`.
///
/// [`count_min_max`][] is a non-`RangeStream` alternative.
///
/// [`count_min_max`]: ../../parser/repeat/fn.count_min_max.html
/// ```
/// # extern crate combine;
/// # use combine::parser::range::take;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take(1);
/// let result = parser.parse("1");
/// assert_eq!(result, Ok(("1", "")));
/// let mut parser = take(4);
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123a", "bc")));
/// let result = parser.parse("abc");
/// assert!(result.is_err());
/// # }
/// ```
pub fn take<Input>(n: usize) -> Take<Input>
where
Input: RangeStream,
{
Take(n, PhantomData)
}
pub struct TakeWhile<Input, F>(F, PhantomData<fn(Input) -> Input>);
impl<Input, F> Parser<Input> for TakeWhile<Input, F>
where
Input: RangeStream,
Input::Range: crate::stream::Range,
F: FnMut(Input::Token) -> bool,
{
type Output = Input::Range;
type PartialState = usize;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
parse_partial_range(
mode,
input,
state,
&mut self.0,
|input, predicate| uncons_while(input, predicate),
|input, predicate| uncons_while(input, predicate),
)
}
}
/// Zero-copy parser which reads a range of 0 or more tokens which satisfy `f`.
///
/// [`many`][] is a non-`RangeStream` alternative.
///
/// [`many`]: ../../parser/repeat/fn.many.html
/// ```
/// # extern crate combine;
/// # use combine::parser::range::take_while;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_while(|c: char| c.is_digit(10));
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123", "abc")));
/// let result = parser.parse("abc");
/// assert_eq!(result, Ok(("", "abc")));
/// # }
/// ```
pub fn take_while<Input, F>(f: F) -> TakeWhile<Input, F>
where
Input: RangeStream,
Input::Range: crate::stream::Range,
F: FnMut(Input::Token) -> bool,
{
TakeWhile(f, PhantomData)
}
pub struct TakeWhile1<Input, F>(F, PhantomData<fn(Input) -> Input>);
impl<Input, F> Parser<Input> for TakeWhile1<Input, F>
where
Input: RangeStream,
Input::Range: crate::stream::Range,
F: FnMut(Input::Token) -> bool,
{
type Output = Input::Range;
type PartialState = usize;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
parse_partial_range(
mode,
input,
state,
&mut self.0,
|input, predicate| uncons_while1(input, predicate),
|input, predicate| uncons_while(input, predicate),
)
}
}
/// Zero-copy parser which reads a range of 1 or more tokens which satisfy `f`.
///
/// [`many1`][] is a non-`RangeStream` alternative.
///
/// [`many1`]: ../../parser/repeat/fn.many1.html
/// ```
/// # extern crate combine;
/// # use combine::parser::range::take_while1;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_while1(|c: char| c.is_digit(10));
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123", "abc")));
/// let result = parser.parse("abc");
/// assert!(result.is_err());
/// # }
/// ```
pub fn take_while1<Input, F>(f: F) -> TakeWhile1<Input, F>
where
Input: RangeStream,
Input::Range: crate::stream::Range,
F: FnMut(Input::Token) -> bool,
{
TakeWhile1(f, PhantomData)
}
pub struct TakeUntilRange<Input>(Input::Range)
where
Input: RangeStream;
impl<Input> Parser<Input> for TakeUntilRange<Input>
where
Input: RangeStream,
Input::Range: PartialEq + crate::stream::Range,
{
type Output = Input::Range;
type PartialState = usize;
#[inline]
fn parse_partial(
&mut self,
input: &mut Input,
to_consume: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
use crate::stream::Range;
let len = self.0.len();
let before = input.checkpoint();
let mut first_stream_error = None;
// Skip until the end of the last parse attempt
ctry!(uncons_range(input, *to_consume));
loop {
let look_ahead_input = input.checkpoint();
match input.uncons_range(len) {
Ok(xs) => {
if xs == self.0 {
let distance = input.distance(&before) - len;
ctry!(input.reset(before).committed());
if let Ok(committed) = input.uncons_range(distance) {
if distance == 0 {
return PeekOk(committed);
} else {
*to_consume = 0;
return CommitOk(committed);
}
}
// We are guaranteed able to uncons to_consume characters here
// because we've already done it on look_ahead_input.
unreachable!();
} else {
// Reset the stream back to where it was when we entered the top of the loop
ctry!(input.reset(look_ahead_input).committed());
// Advance the stream by one token
if input.uncons().is_err() {
unreachable!();
}
}
}
Err(first_error) => {
// If we are unable to find a successful parse even after advancing with `uncons`
// below we must reset the stream to its state before the first error.
// If we don't we may try and match the range `::` against `:<EOF>` which would
// fail as only one `:` is present at this parse attempt. But when we later resume
// with more input we must start parsing again at the first time we errored so we
// can see the entire `::`
if first_stream_error.is_none() {
first_stream_error = Some((first_error, input.distance(&before)));
}
// Reset the stream back to where it was when we entered the top of the loop
ctry!(input.reset(look_ahead_input).committed());
// See if we can advance anyway
if input.uncons().is_err() {
let (first_error, first_error_distance) = first_stream_error.unwrap();
// Reset the stream
ctry!(input.reset(before).committed());
*to_consume = first_error_distance;
// Return the original error if uncons failed
return wrap_stream_error(input, first_error);
}
}
};
}
}
}
/// Zero-copy parser which reads a range of 0 or more tokens until `r` is found.
///
/// The range `r` will not be committed. If `r` is not found, the parser will
/// return an error.
///
/// [`repeat::take_until`][] is a non-`RangeStream` alternative.
///
/// [`repeat::take_until`]: ../../parser/repeat/fn.take_until.html
/// ```
/// # extern crate combine;
/// # use combine::parser::range::{range, take_until_range};
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_until_range("\r\n");
/// let result = parser.parse("To: user@example.com\r\n");
/// assert_eq!(result, Ok(("To: user@example.com", "\r\n")));
/// let result = parser.parse("Hello, world\n");
/// assert!(result.is_err());
/// # }
/// ```
pub fn take_until_range<Input>(r: Input::Range) -> TakeUntilRange<Input>
where
Input: RangeStream,
{
TakeUntilRange(r)
}
#[derive(Debug, PartialEq)]
pub enum TakeRange {
/// Found the pattern at this offset
Found(usize),
/// Did not find the pattern but the parser can skip ahead to this offset.
NotFound(usize),
}
impl From<Option<usize>> for TakeRange {
fn from(opt: Option<usize>) -> TakeRange {
match opt {
Some(i) => TakeRange::Found(i),
None => TakeRange::NotFound(0),
}
}
}
pub struct TakeFn<F, Input> {
searcher: F,
_marker: PhantomData<fn(Input)>,
}
impl<Input, F, R> Parser<Input> for TakeFn<F, Input>
where
F: FnMut(Input::Range) -> R,
R: Into<TakeRange>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
type Output = Input::Range;
type PartialState = usize;
parse_mode!(Input);
#[inline]
fn parse_mode<M>(
&mut self,
mode: M,
input: &mut Input,
offset: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
let checkpoint = input.checkpoint();
if mode.is_first() {
*offset = 0;
} else {
let _ = input.uncons_range(*offset);
}
match (self.searcher)(input.range()).into() {
TakeRange::Found(i) => {
ctry!(input.reset(checkpoint).committed());
let result = uncons_range(input, *offset + i);
if result.is_ok() {
*offset = 0;
}
result
}
TakeRange::NotFound(next_offset) => {
*offset = next_offset;
let range = input.range();
let _ = input.uncons_range(range.len());
let position = input.position();
ctry!(input.reset(checkpoint).committed());
let err = Input::Error::from_error(position, StreamError::end_of_input());
if !input.is_partial() && range.is_empty() {
PeekErr(err.into())
} else {
CommitErr(err)
}
}
}
}
}
/// Searches the entire range using `searcher` and then consumes a range of `Some(n)`.
/// If `f` can not find anything in the range it must return `None/NotFound` which indicates an end of input error.
///
/// If partial parsing is used the `TakeRange` enum can be returned instead of `Option`. By
/// returning `TakeRange::NotFound(n)` it indicates that the input can skip ahead until `n`
/// when parsing is next resumed.
///
/// See [`take_until_bytes`](../byte/fn.take_until_bytes.html) for a usecase.
pub fn take_fn<F, R, Input>(searcher: F) -> TakeFn<F, Input>
where
F: FnMut(Input::Range) -> R,
R: Into<TakeRange>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
TakeFn {
searcher,
_marker: PhantomData,
}
}
#[cfg(feature = "std")]
parser! {
/// Takes a parser which parses a `length` then extracts a range of that length and returns it.
/// Commonly used in binary formats
///
/// ```
/// # use combine::parser::{byte::num::be_u16, range::length_prefix};
/// # use combine::*;
/// # fn main() {
/// let mut input = Vec::new();
/// input.extend_from_slice(&3u16.to_be_bytes());
/// input.extend_from_slice(b"1234");
///
/// let mut parser = length_prefix(be_u16());
/// let result = parser.parse(&input[..]);
/// assert_eq!(result, Ok((&b"123"[..], &b"4"[..])));
/// # }
/// ```
pub fn length_prefix[Input, P](len: P)(Input) -> Input::Range
where [
Input: RangeStream,
P: Parser<Input>,
usize: TryFrom<P::Output>,
<usize as TryFrom<P::Output>>::Error: StdError + Send + Sync + 'static,
]
{
len
.and_then(|u| {
usize::try_from(u)
.map_err(StreamErrorFor::<Input>::other)
})
.then_partial(|&mut len| take(len))
}
}
#[cfg(not(feature = "std"))]
parser! {
/// Takes a parser which parses a `length` then extracts a range of that length and returns it.
/// Commonly used in binary formats
///
/// ```
/// # use combine::parser::{byte::num::be_u16, range::length_prefix};
/// # use combine::*;
/// # fn main() {
/// let mut input = Vec::new();
/// input.extend_from_slice(&3u16.to_be_bytes());
/// input.extend_from_slice(b"1234");
///
/// let mut parser = length_prefix(be_u16());
/// let result = parser.parse(&input[..]);
/// assert_eq!(result, Ok((&b"123"[..], &b"4"[..])));
/// # }
/// ```
pub fn length_prefix[Input, P](len: P)(Input) -> Input::Range
where [
Input: RangeStream,
P: Parser<Input>,
usize: TryFrom<P::Output>,
<usize as TryFrom<P::Output>>::Error: fmt::Display + Send + Sync + 'static,
]
{
len
.and_then(|u| {
usize::try_from(u)
.map_err(StreamErrorFor::<Input>::message_format)
})
.then_partial(|&mut len| take(len))
}
}
#[cfg(test)]
mod tests {
use crate::Parser;
use super::*;
#[test]
fn take_while_test() {
let result = take_while(|c: char| c.is_digit(10)).parse("123abc");
assert_eq!(result, Ok(("123", "abc")));
let result = take_while(|c: char| c.is_digit(10)).parse("abc");
assert_eq!(result, Ok(("", "abc")));
}
#[test]
fn take_while1_test() {
let result = take_while1(|c: char| c.is_digit(10)).parse("123abc");
assert_eq!(result, Ok(("123", "abc")));
let result = take_while1(|c: char| c.is_digit(10)).parse("abc");
assert!(result.is_err());
}
#[test]
fn range_string_no_char_boundary_error() {
let mut parser = range("hello");
let result = parser.parse("hell\u{00EE} world");
assert!(result.is_err());
}
#[test]
fn take_until_range_1() {
let result = take_until_range("\"").parse("Foo baz bar quux\"");
assert_eq!(result, Ok(("Foo baz bar quux", "\"")));
}
#[test]
fn take_until_range_2() {
let result = take_until_range("===").parse("if ((pointless_comparison == 3) === true) {");
assert_eq!(
result,
Ok(("if ((pointless_comparison == 3) ", "=== true) {"))
);
}
#[test]
fn take_until_range_unicode_1() {
let result = take_until_range("🦀")
.parse("😃 Ferris the friendly rustacean 🦀 and his snake friend 🐍");
assert_eq!(
result,
Ok((
"😃 Ferris the friendly rustacean ",
"🦀 and his snake friend 🐍"
))
);
}
#[test]
fn take_until_range_unicode_2() {
let result = take_until_range("⁘⁙/⁘").parse("⚙️🛠️🦀=🏎️⁘⁙⁘⁘⁙/⁘⁘⁙/⁘");
assert_eq!(result, Ok(("⚙️🛠️🦀=🏎️⁘⁙⁘", "⁘⁙/⁘⁘⁙/⁘")));
}
}

549
vendor/combine/src/parser/regex.rs vendored Normal file
View File

@@ -0,0 +1,549 @@
//! Module containing regex parsers on streams returning ranges of `&str` or `&[u8]`.
//!
//! All regex parsers are overloaded on `&str` and `&[u8]` ranges and can take a `Regex` by value
//! or shared reference (`&`).
//!
//! Enabled using the `regex` feature (for `regex-0.2`) or the `regex-1` feature for `regex-1.0`.
//!
//! ```
//! use once_cell::sync::Lazy;
//! use regex::{bytes, Regex};
//! use combine::Parser;
//! use combine::parser::regex::{find_many, match_};
//!
//! fn main() {
//! let regex = bytes::Regex::new("[0-9]+").unwrap();
//! // Shared references to any regex works as well
//! assert_eq!(
//! find_many(&regex).parse(&b"123 456 "[..]),
//! Ok((vec![&b"123"[..], &b"456"[..]], &b" "[..]))
//! );
//! assert_eq!(
//! find_many(regex).parse(&b""[..]),
//! Ok((vec![], &b""[..]))
//! );
//!
//! static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new("[:alpha:]+").unwrap());
//! assert_eq!(
//! match_(&*REGEX).parse("abc123"),
//! Ok(("abc123", "abc123"))
//! );
//! }
//! ```
use std::{iter::FromIterator, marker::PhantomData};
use crate::{
error::{
ParseError,
ParseResult::{self, *},
StreamError, Tracked,
},
parser::range::take,
stream::{RangeStream, StreamOnce},
Parser,
};
struct First<T>(Option<T>);
impl<A> FromIterator<A> for First<A> {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = A>,
{
First(iter.into_iter().next())
}
}
pub trait MatchFind {
type Range;
fn end(&self) -> usize;
fn as_match(&self) -> Self::Range;
}
pub trait Regex<Range> {
fn is_match(&self, range: Range) -> bool;
fn find_iter<F>(&self, range: Range) -> (usize, F)
where
F: FromIterator<Range>;
fn captures<F, G>(&self, range: Range) -> (usize, G)
where
F: FromIterator<Range>,
G: FromIterator<F>;
fn as_str(&self) -> &str;
}
impl<'a, R, Range> Regex<Range> for &'a R
where
R: Regex<Range>,
{
fn is_match(&self, range: Range) -> bool {
(**self).is_match(range)
}
fn find_iter<F>(&self, range: Range) -> (usize, F)
where
F: FromIterator<Range>,
{
(**self).find_iter(range)
}
fn captures<F, G>(&self, range: Range) -> (usize, G)
where
F: FromIterator<Range>,
G: FromIterator<F>,
{
(**self).captures(range)
}
fn as_str(&self) -> &str {
(**self).as_str()
}
}
fn find_iter<'a, Input, F>(iterable: Input) -> (usize, F)
where
Input: IntoIterator,
Input::Item: MatchFind,
F: FromIterator<<Input::Item as MatchFind>::Range>,
{
let mut end = 0;
let value = iterable
.into_iter()
.map(|m| {
end = m.end();
m.as_match()
})
.collect();
(end, value)
}
#[cfg(feature = "regex")]
mod regex {
pub extern crate regex;
use std::iter::FromIterator;
use super::{find_iter, MatchFind, Regex};
pub use self::regex::*;
impl<'t> MatchFind for regex::Match<'t> {
type Range = &'t str;
fn end(&self) -> usize {
regex::Match::end(self)
}
fn as_match(&self) -> Self::Range {
self.as_str()
}
}
impl<'t> MatchFind for regex::bytes::Match<'t> {
type Range = &'t [u8];
fn end(&self) -> usize {
regex::bytes::Match::end(self)
}
fn as_match(&self) -> Self::Range {
self.as_bytes()
}
}
impl<'a> Regex<&'a str> for regex::Regex {
fn is_match(&self, range: &'a str) -> bool {
regex::Regex::is_match(self, range)
}
fn find_iter<F>(&self, range: &'a str) -> (usize, F)
where
F: FromIterator<&'a str>,
{
find_iter(regex::Regex::find_iter(self, range))
}
fn captures<F, G>(&self, range: &'a str) -> (usize, G)
where
F: FromIterator<&'a str>,
G: FromIterator<F>,
{
let mut end = 0;
let value = regex::Regex::captures_iter(self, range)
.map(|captures| {
let mut captures_iter = captures.iter();
// The first group is the match on the entire regex
let first_match = captures_iter.next().unwrap().unwrap();
end = first_match.end();
Some(Some(first_match))
.into_iter()
.chain(captures_iter)
.filter_map(|match_| match_.map(|m| m.as_match()))
.collect()
})
.collect();
(end, value)
}
fn as_str(&self) -> &str {
regex::Regex::as_str(self)
}
}
impl<'a> Regex<&'a [u8]> for regex::bytes::Regex {
fn is_match(&self, range: &'a [u8]) -> bool {
regex::bytes::Regex::is_match(self, range)
}
fn find_iter<F>(&self, range: &'a [u8]) -> (usize, F)
where
F: FromIterator<&'a [u8]>,
{
find_iter(regex::bytes::Regex::find_iter(self, range))
}
fn captures<F, G>(&self, range: &'a [u8]) -> (usize, G)
where
F: FromIterator<&'a [u8]>,
G: FromIterator<F>,
{
let mut end = 0;
let value = regex::bytes::Regex::captures_iter(self, range)
.map(|captures| {
let mut captures_iter = captures.iter();
// The first group is the match on the entire regex
let first_match = captures_iter.next().unwrap().unwrap();
end = first_match.end();
Some(Some(first_match))
.into_iter()
.chain(captures_iter)
.filter_map(|match_| match_.map(|m| m.as_match()))
.collect()
})
.collect();
(end, value)
}
fn as_str(&self) -> &str {
regex::bytes::Regex::as_str(self)
}
}
}
pub struct Match<R, Input>(R, PhantomData<Input>);
impl<'a, Input, R> Parser<Input> for Match<R, Input>
where
R: Regex<Input::Range>,
Input: RangeStream,
{
type Output = Input::Range;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
if self.0.is_match(input.range()) {
PeekOk(input.range())
} else {
PeekErr(Input::Error::empty(input.position()).into())
}
}
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
error.error.add(StreamError::expected_format(format_args!(
"/{}/",
self.0.as_str()
)))
}
}
/// Matches `regex` on the input returning the entire input if it matches.
/// Never consumes any input.
///
/// ```
/// extern crate regex;
/// extern crate combine;
/// use regex::Regex;
/// use combine::Parser;
/// use combine::parser::regex::match_;
///
/// fn main() {
/// let regex = Regex::new("[:alpha:]+").unwrap();
/// assert_eq!(
/// match_(&regex).parse("abc123"),
/// Ok(("abc123", "abc123"))
/// );
/// }
/// ```
pub fn match_<R, Input>(regex: R) -> Match<R, Input>
where
R: Regex<Input::Range>,
Input: RangeStream,
{
Match(regex, PhantomData)
}
#[derive(Clone)]
pub struct Find<R, Input>(R, PhantomData<fn() -> Input>);
impl<'a, Input, R> Parser<Input> for Find<R, Input>
where
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
type Output = Input::Range;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let (end, First(value)) = self.0.find_iter(input.range());
match value {
Some(value) => take(end).parse_lazy(input).map(|_| value),
None => PeekErr(Input::Error::empty(input.position()).into()),
}
}
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
error.error.add(StreamError::expected_format(format_args!(
"/{}/",
self.0.as_str()
)))
}
}
/// Matches `regex` on the input by running `find` on the input and returns the first match.
/// Consumes all input up until the end of the first match.
///
/// ```
/// extern crate regex;
/// extern crate combine;
/// use regex::Regex;
/// use combine::Parser;
/// use combine::parser::regex::find;
///
/// fn main() {
/// let mut digits = find(Regex::new("^[0-9]+").unwrap());
/// assert_eq!(digits.parse("123 456 "), Ok(("123", " 456 ")));
/// assert!(
/// digits.parse("abc 123 456 ").is_err());
///
/// let mut digits2 = find(Regex::new("[0-9]+").unwrap());
/// assert_eq!(digits2.parse("123 456 "), Ok(("123", " 456 ")));
/// assert_eq!(digits2.parse("abc 123 456 "), Ok(("123", " 456 ")));
/// }
/// ```
pub fn find<R, Input>(regex: R) -> Find<R, Input>
where
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
Find(regex, PhantomData)
}
#[derive(Clone)]
pub struct FindMany<F, R, Input>(R, PhantomData<fn() -> (Input, F)>);
impl<'a, Input, F, R> Parser<Input> for FindMany<F, R, Input>
where
F: FromIterator<Input::Range>,
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
type Output = F;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let (end, value) = self.0.find_iter(input.range());
take(end).parse_lazy(input).map(|_| value)
}
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
error.error.add(StreamError::expected_format(format_args!(
"/{}/",
self.0.as_str()
)))
}
}
/// Matches `regex` on the input by running `find_iter` on the input.
/// Returns all matches in a `F: FromIterator<Input::Range>`.
/// Consumes all input up until the end of the last match.
///
/// ```
/// extern crate regex;
/// extern crate combine;
/// use regex::Regex;
/// use regex::bytes;
/// use combine::Parser;
/// use combine::parser::regex::find_many;
///
/// fn main() {
/// let mut digits = find_many(Regex::new("[0-9]+").unwrap());
/// assert_eq!(digits.parse("123 456 "), Ok((vec!["123", "456"], " ")));
/// assert_eq!(digits.parse("abc 123 456 "), Ok((vec!["123", "456"], " ")));
/// assert_eq!(digits.parse("abc"), Ok((vec![], "abc")));
/// }
/// ```
pub fn find_many<F, R, Input>(regex: R) -> FindMany<F, R, Input>
where
F: FromIterator<Input::Range>,
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
FindMany(regex, PhantomData)
}
#[derive(Clone)]
pub struct Captures<F, R, Input>(R, PhantomData<fn() -> (Input, F)>);
impl<'a, Input, F, R> Parser<Input> for Captures<F, R, Input>
where
F: FromIterator<Input::Range>,
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
type Output = F;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let (end, First(value)) = self.0.captures(input.range());
match value {
Some(value) => take(end).parse_lazy(input).map(|_| value),
None => PeekErr(Input::Error::empty(input.position()).into()),
}
}
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
error.error.add(StreamError::expected_format(format_args!(
"/{}/",
self.0.as_str()
)))
}
}
/// Matches `regex` on the input by running `captures_iter` on the input.
/// Returns the captures of the first match and consumes the input up until the end of that match.
///
/// ```
/// extern crate regex;
/// extern crate combine;
/// use regex::Regex;
/// use combine::Parser;
/// use combine::parser::regex::captures;
///
/// fn main() {
/// let mut fields = captures(Regex::new("([a-z]+):([0-9]+)").unwrap());
/// assert_eq!(
/// fields.parse("test:123 field:456 "),
/// Ok((vec!["test:123", "test", "123"],
/// " field:456 "
/// ))
/// );
/// assert_eq!(
/// fields.parse("test:123 :456 "),
/// Ok((vec!["test:123", "test", "123"],
/// " :456 "
/// ))
/// );
/// }
/// ```
pub fn captures<F, R, Input>(regex: R) -> Captures<F, R, Input>
where
F: FromIterator<Input::Range>,
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
Captures(regex, PhantomData)
}
#[derive(Clone)]
pub struct CapturesMany<F, G, R, Input>(R, PhantomData<fn() -> (Input, F, G)>);
impl<'a, Input, F, G, R> Parser<Input> for CapturesMany<F, G, R, Input>
where
F: FromIterator<Input::Range>,
G: FromIterator<F>,
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
type Output = G;
type PartialState = ();
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
let (end, value) = self.0.captures(input.range());
take(end).parse_lazy(input).map(|_| value)
}
fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
error.error.add(StreamError::expected_format(format_args!(
"/{}/",
self.0.as_str()
)))
}
}
/// Matches `regex` on the input by running `captures_iter` on the input.
/// Returns all captures which is part of the match in a `F: FromIterator<Input::Range>`.
/// Consumes all input up until the end of the last match.
///
/// ```
/// extern crate regex;
/// extern crate combine;
/// use regex::Regex;
/// use combine::Parser;
/// use combine::parser::regex::captures_many;
///
/// fn main() {
/// let mut fields = captures_many(Regex::new("([a-z]+):([0-9]+)").unwrap());
/// assert_eq!(
/// fields.parse("test:123 field:456 "),
/// Ok((vec![vec!["test:123", "test", "123"],
/// vec!["field:456", "field", "456"]],
/// " "
/// ))
/// );
/// assert_eq!(
/// fields.parse("test:123 :456 "),
/// Ok((vec![vec!["test:123", "test", "123"]],
/// " :456 "
/// ))
/// );
/// }
/// ```
pub fn captures_many<F, G, R, Input>(regex: R) -> CapturesMany<F, G, R, Input>
where
F: FromIterator<Input::Range>,
G: FromIterator<F>,
R: Regex<Input::Range>,
Input: RangeStream,
Input::Range: crate::stream::Range,
{
CapturesMany(regex, PhantomData)
}
#[cfg(test)]
mod tests {
use regex::Regex;
use crate::{parser::regex::find, Parser};
#[test]
fn test() {
let mut digits = find(Regex::new("^[0-9]+").unwrap());
assert_eq!(digits.parse("123 456 "), Ok(("123", " 456 ")));
assert!(digits.parse("abc 123 456 ").is_err());
let mut digits2 = find(Regex::new("[0-9]+").unwrap());
assert_eq!(digits2.parse("123 456 "), Ok(("123", " 456 ")));
assert_eq!(digits2.parse("abc 123 456 "), Ok(("123", " 456 ")));
}
}

1620
vendor/combine/src/parser/repeat.rs vendored Normal file

File diff suppressed because it is too large Load Diff

907
vendor/combine/src/parser/sequence.rs vendored Normal file
View File

@@ -0,0 +1,907 @@
//! Combinators which take multiple parsers and applies them one after another.
use crate::{
error::{
ParseError,
ParseResult::{self, *},
StreamError, Tracked,
},
lib::marker::PhantomData,
parser::{
combinator::{ignore, Ignore, Map},
ParseMode,
},
ErrorOffset, Parser, Stream, StreamOnce,
};
macro_rules! count {
() => { 0 };
($f: ident) => { 1 };
($f: ident, $($rest: ident),+) => { 1 + count!($($rest),*) };
}
#[doc(hidden)]
pub struct SequenceState<T, U> {
pub value: Option<T>,
pub state: U,
}
impl<T, U: Default> Default for SequenceState<T, U> {
fn default() -> Self {
SequenceState {
value: None,
state: U::default(),
}
}
}
impl<T, U> SequenceState<T, U>
where
U: Default,
{
unsafe fn unwrap_value(&mut self) -> T {
match self.value.take() {
Some(t) => t,
None => core::hint::unreachable_unchecked(),
}
}
}
macro_rules! last_ident {
($id: ident) => { $id };
($id: ident, $($rest: ident),+) => { last_ident!($($rest),+) };
}
fn add_sequence_error<Input>(
i: &mut usize,
first_empty_parser: usize,
inner_offset: ErrorOffset,
err: &mut Tracked<Input::Error>,
parser: &mut impl Parser<Input>,
) -> bool
where
Input: Stream,
{
if *i + 1 == first_empty_parser {
Parser::add_committed_expected_error(parser, err);
}
if *i >= first_empty_parser {
if err.offset <= ErrorOffset(1) {
// We reached the last parser we need to add errors to (and the
// parser that actually returned the error), use the returned
// offset for that parser.
err.offset = inner_offset;
}
Parser::add_error(parser, err);
if err.offset <= ErrorOffset(1) {
return false;
}
}
err.offset = ErrorOffset(err.offset.0.saturating_sub(Parser::parser_count(parser).0));
*i += 1;
true
}
macro_rules! tuple_parser {
($partial_state: ident; $h: ident $(, $id: ident)*) => {
#[allow(non_snake_case)]
#[derive(Default)]
pub struct $partial_state < $h $(, $id )* > {
pub $h: $h,
$(
pub $id: $id,
)*
#[allow(dead_code)]
offset: u8,
_marker: PhantomData <( $h, $( $id),* )>,
}
#[allow(non_snake_case)]
impl<$h $(, $id)*> $partial_state<$h $(, $id)*> {
#[allow(dead_code)]
fn add_errors<Input>(
input: &mut Input,
mut err: Tracked<Input::Error>,
first_empty_parser: usize,
offset: u8,
$h: &mut $h $(, $id : &mut $id )*
) -> ParseResult<($h::Output, $($id::Output),*), <Input as StreamOnce>::Error>
where Input: Stream,
$h: Parser<Input>,
$($id: Parser<Input>),*
{
let inner_offset = err.offset;
err.offset = ErrorOffset(offset);
if first_empty_parser != 0 {
if let Ok(t) = input.uncons() {
err.error.add(StreamError::unexpected_token(t));
}
#[allow(unused_assignments)]
let mut i = 0;
loop {
if !add_sequence_error(&mut i, first_empty_parser, inner_offset, &mut err, $h) {
break;
}
$(
if !add_sequence_error(&mut i, first_empty_parser, inner_offset, &mut err, $id) {
break;
}
)*
break;
}
CommitErr(err.error)
} else {
PeekErr(err)
}
}
}
#[allow(non_snake_case)]
impl <Input: Stream, $h:, $($id:),*> Parser<Input> for ($h, $($id),*)
where Input: Stream,
$h: Parser<Input>,
$($id: Parser<Input>),*
{
type Output = ($h::Output, $($id::Output),*);
type PartialState = $partial_state<
SequenceState<$h::Output, $h::PartialState>
$(, SequenceState<$id::Output, $id::PartialState>)*
>;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<MODE>(
&mut self,
mut mode: MODE,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
MODE: ParseMode,
{
let (ref mut $h, $(ref mut $id),*) = *self;
let mut first_empty_parser = 0;
#[allow(unused_mut)]
let mut current_parser = 0;
#[allow(unused_macros)]
macro_rules! add_errors {
($err: ident, $offset: expr) => {
$partial_state::add_errors(
input, $err, first_empty_parser, $offset, $h, $($id),*
)
}
}
if mode.is_first() || state.$h.value.is_none() {
let temp = match $h.parse_mode(mode, input, &mut state.$h.state) {
CommitOk(x) => {
first_empty_parser = current_parser + 1;
x
}
PeekErr(err) => return PeekErr(err),
CommitErr(err) => return CommitErr(err),
PeekOk(x) => {
x
}
};
state.offset = $h.parser_count().0.saturating_add(1);
// SAFETY: must be set to avoid UB below when unwrapping
state.$h.value = Some(temp);
// Once we have successfully parsed the partial input we may resume parsing in
// "first mode"
mode.set_first();
}
$(
if mode.is_first() || state.$id.value.is_none() {
current_parser += 1;
let before = input.checkpoint();
let temp = match $id.parse_mode(mode, input, &mut state.$id.state) {
CommitOk(x) => {
first_empty_parser = current_parser + 1;
x
}
PeekErr(err) => {
if let Err(err) = input.reset(before) {
return if first_empty_parser != 0 {
CommitErr(err.into())
} else {
PeekErr(err.into())
};
}
return add_errors!(err, state.offset)
}
CommitErr(err) => return CommitErr(err),
PeekOk(x) => {
x
}
};
state.offset = state.offset.saturating_add($id.parser_count().0);
// SAFETY: must be set to avoid UB below when unwrapping
state.$id.value = Some(temp);
// Once we have successfully parsed the partial input we may resume parsing in
// "first mode"
mode.set_first();
}
)*
// SAFETY: requires both $h and $id to be set, see previous SAFETY comments
let value = unsafe { (state.$h.unwrap_value(), $(state.$id.unwrap_value()),*) };
if first_empty_parser != 0 {
CommitOk(value)
} else {
PeekOk(value)
}
}
#[inline]
fn parser_count(&self) -> ErrorOffset {
let (ref $h, $(ref $id),*) = *self;
ErrorOffset($h.parser_count().0 $( + $id.parser_count().0)*)
}
#[inline]
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
let (ref mut $h, $(ref mut $id),*) = *self;
let prev = errors.offset;
$h.add_error(errors);
if errors.offset <= ErrorOffset(1) {
errors.offset = ErrorOffset(
errors.offset.0.saturating_sub(1)
);
return;
}
if errors.offset == prev {
errors.offset = ErrorOffset(errors.offset.0.saturating_sub($h.parser_count().0));
}
#[allow(dead_code)]
const LAST: usize = count!($($id),*);
#[allow(unused_mut, unused_variables)]
let mut i = 0;
$(
i += 1;
let prev = errors.offset;
$id.add_error(errors);
if errors.offset <= ErrorOffset(1) {
errors.offset = ErrorOffset(
errors.offset.0.saturating_sub(1)
);
return;
}
if i != LAST && errors.offset == prev {
errors.offset = ErrorOffset(
errors.offset.0.saturating_sub($id.parser_count().0)
);
}
)*
}
fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
#[allow(unused_variables)]
let (ref mut $h, $(ref mut $id),*) = *self;
last_ident!($h $(, $id)*).add_committed_expected_error(errors)
}
}
}
}
tuple_parser!(PartialState1; A);
tuple_parser!(PartialState2; A, B);
tuple_parser!(PartialState3; A, B, C);
tuple_parser!(PartialState4; A, B, C, D);
tuple_parser!(PartialState5; A, B, C, D, E);
tuple_parser!(PartialState6; A, B, C, D, E, F);
tuple_parser!(PartialState7; A, B, C, D, E, F, G);
tuple_parser!(PartialState8; A, B, C, D, E, F, G, H);
tuple_parser!(PartialState9; A, B, C, D, E, F, G, H, I);
tuple_parser!(PartialState10; A, B, C, D, E, F, G, H, I, J);
tuple_parser!(PartialState11; A, B, C, D, E, F, G, H, I, J, K);
tuple_parser!(PartialState12; A, B, C, D, E, F, G, H, I, J, K, L);
tuple_parser!(PartialState13; A, B, C, D, E, F, G, H, I, J, K, L, M);
tuple_parser!(PartialState14; A, B, C, D, E, F, G, H, I, J, K, L, M, N);
tuple_parser!(PartialState15; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P);
tuple_parser!(PartialState16; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q);
tuple_parser!(PartialState17; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R);
tuple_parser!(PartialState18; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S);
tuple_parser!(PartialState19; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T);
tuple_parser!(PartialState20; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T, U);
#[macro_export]
#[doc(hidden)]
macro_rules! seq_parser_expr {
(; $($tt: tt)*) => {
( $($tt)* )
};
( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
$crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
};
( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
$crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
};
( (_ : $first_parser: expr ); $($tt: tt)*) => {
( $($tt)* $first_parser, )
};
( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
$crate::seq_parser_expr!(; $($tt)* $first_parser,)
};
( (_ : $first_parser: expr, ); $($tt: tt)*) => {
( $($tt)* $first_parser, )
};
( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
$crate::seq_parser_expr!(; $($tt)* $first_parser,)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! seq_parser_pattern {
(; $($tt: tt)*) => {
( $($tt)* )
};
( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
$crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* _, )
};
( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
$crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* $first_field, )
};
( ( _ : $first_parser: expr ); $($tt: tt)*) => {
$crate::seq_parser_pattern!(; $($tt)* _, )
};
( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
$crate::seq_parser_pattern!(; $($tt)* $first_field,)
};
( ( _ : $first_parser: expr, ); $($tt: tt)*) => {
$crate::seq_parser_pattern!(; $($tt)* _, )
};
( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
$crate::seq_parser_pattern!(; $($tt)* $first_field,)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! seq_parser_impl {
(; $name: ident $($tt: tt)*) => {
$name { $($tt)* }
};
( (_ : $first_parser: expr, $($remaining: tt)+ ); $name: ident $($tt: tt)*) => {
$crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* )
};
( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ );
$name: ident $($tt: tt)*) =>
{
$crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* $first_field: $first_field, )
};
( ( _ : $first_parser: expr ); $name: ident $($tt: tt)*) => {
$crate::seq_parser_impl!( ; $name $($tt)* )
};
( ($first_field: ident : $first_parser: expr ); $name: ident $($tt: tt)*) => {
$crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
};
( ( _ : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
$crate::seq_parser_impl!(; $name $($tt)*)
};
( ($first_field: ident : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
$crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! seq_tuple_extract {
(; ; $name: ident ; $($arg: expr),* $(,)? ) => {
$name( $($arg,)* )
};
( (_ : $first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
$crate::seq_tuple_extract!( ( $($remaining)+ ); ( $($arg),* ) ; $($tt)* )
};
( ($first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
$crate::seq_tuple_extract!( ( $($remaining)+ ) ; ( $($arg),* ) ; $($tt)* $first_arg, )
};
( (_ : $first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
$crate::seq_tuple_extract!(; ; $($tt)*)
};
( ($first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
$crate::seq_tuple_extract!(; ; $($tt)* $first_arg)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! seq_tuple_parser_impl {
(; $($tt: tt)*) => {
($($tt)*)
};
( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
$crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
};
( ($first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
$crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
};
( (_ : $first_parser: expr $(,)? ); $($tt: tt)*) => {
$crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
};
( ($first_parser: expr $(,)? ); $($tt: tt)*) => {
$crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
};
}
/// Sequences multiple parsers and builds a struct out of them.
///
/// ```
/// use combine::{Parser, between, from_str, many, struct_parser, token};
/// use combine::parser::range::take_while1;
/// use combine::parser::byte::{letter, spaces};
///
/// #[derive(Debug, PartialEq)]
/// struct Point(u32, u32);
///
/// #[derive(Debug, PartialEq)]
/// struct Field {
/// name: Vec<u8>,
/// value: Vec<u8>,
/// point: Point,
/// }
/// fn main() {
/// let num = || from_str(take_while1(|b: u8| b >= b'0' && b <= b'9'));
/// let spaced = |b| between(spaces(), spaces(), token(b));
/// let mut parser = struct_parser!{
/// Field {
/// name: many(letter()),
/// // `_` fields are ignored when building the struct
/// _: spaced(b':'),
/// value: many(letter()),
/// _: spaced(b':'),
/// point: struct_parser!(Point(num(), _: spaced(b','), num())),
/// }
/// };
/// assert_eq!(
/// parser.parse(&b"test: data: 123 , 4"[..]),
/// Ok((
/// Field {
/// name: b"test"[..].to_owned(),
/// value: b"data"[..].to_owned(),
/// point: Point(123, 4),
/// },
/// &b""[..]
/// )),
/// );
/// }
/// ```
#[macro_export]
macro_rules! struct_parser {
($name: ident { $($tt: tt)* }) => {
$crate::seq_parser_expr!( ( $($tt)* ); )
.map(|$crate::seq_parser_pattern!( ( $($tt)* ); )|
$crate::seq_parser_impl!(( $($tt)* ); $name )
)
};
($name: ident ( $($arg: tt)* )) => {
$crate::seq_tuple_parser_impl!( ( $($arg)* ) ; )
.map(|t|
$crate::seq_tuple_extract!(
( $($arg)* );
(t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, t.8, t.9, t.10, t.11, t.12, t.13, t.14);
$name ;
)
)
}
}
#[derive(Copy, Clone)]
pub struct With<P1, P2>((Ignore<P1>, P2));
impl<Input, P1, P2> Parser<Input> for With<P1, P2>
where
Input: Stream,
P1: Parser<Input>,
P2: Parser<Input>,
{
type Output = P2::Output;
type PartialState = <(Ignore<P1>, P2) as Parser<Input>>::PartialState;
#[inline]
fn parse_lazy(
&mut self,
input: &mut Input,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
self.0.parse_lazy(input).map(|(_, b)| b)
}
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
self.0.parse_mode(mode, input, state).map(|(_, b)| b)
}
forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
}
/// Equivalent to [`p1.with(p2)`].
///
/// [`p1.with(p2)`]: ../trait.Parser.html#method.with
pub fn with<Input, P1, P2>(p1: P1, p2: P2) -> With<P1, P2>
where
Input: Stream,
P1: Parser<Input>,
P2: Parser<Input>,
{
With((ignore(p1), p2))
}
#[derive(Copy, Clone)]
pub struct Skip<P1, P2>((P1, Ignore<P2>));
impl<Input, P1, P2> Parser<Input> for Skip<P1, P2>
where
Input: Stream,
P1: Parser<Input>,
P2: Parser<Input>,
{
type Output = P1::Output;
type PartialState = <(P1, Ignore<P2>) as Parser<Input>>::PartialState;
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
self.0.parse_mode(mode, input, state).map(|(a, _)| a)
}
forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
}
pub fn skip<Input, P1, P2>(p1: P1, p2: P2) -> Skip<P1, P2>
where
Input: Stream,
P1: Parser<Input>,
P2: Parser<Input>,
{
Skip((p1, ignore(p2)))
}
parser! {
#[derive(Copy, Clone)]
pub struct Between;
type PartialState = <Map<(L, P, R), fn ((L::Output, P::Output, R::Output)) -> P::Output> as Parser<Input>>::PartialState;
/// Parses `open` followed by `parser` followed by `close`.
/// Returns the value of `parser`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::string;
/// # fn main() {
/// let result = between(token('['), token(']'), string("rust"))
/// .parse("[rust]")
/// .map(|x| x.0);
/// assert_eq!(result, Ok("rust"));
/// # }
/// ```
pub fn between[Input, L, R, P](open: L, close: R, parser: P)(Input) -> P::Output
where [
Input: Stream,
L: Parser< Input>,
R: Parser< Input>,
P: Parser< Input>,
]
{
fn middle<T, U, V>((_, x, _): (T, U, V)) -> U {
x
}
(open, parser, close).map(middle)
}
}
#[derive(Copy, Clone)]
pub struct Then<P, F>(P, F);
impl<Input, P, N, F> Parser<Input> for Then<P, F>
where
Input: Stream,
F: FnMut(P::Output) -> N,
P: Parser<Input>,
N: Parser<Input>,
{
type Output = N::Output;
type PartialState = (P::PartialState, Option<(bool, N)>, N::PartialState);
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mut mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
if mode.is_first() || n_parser_cache.is_none() {
debug_assert!(n_parser_cache.is_none());
let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
PeekOk(value) => (value, false),
CommitOk(value) => (value, true),
PeekErr(err) => return PeekErr(err),
CommitErr(err) => return CommitErr(err),
};
*n_parser_cache = Some((committed, (self.1)(value)));
mode.set_first();
}
let result = n_parser_cache
.as_mut()
.unwrap()
.1
.parse_committed_mode(mode, input, n_state);
match result {
PeekOk(x) => {
let (committed, _) = *n_parser_cache.as_ref().unwrap();
*n_parser_cache = None;
if committed {
CommitOk(x)
} else {
PeekOk(x)
}
}
CommitOk(x) => {
*n_parser_cache = None;
CommitOk(x)
}
PeekErr(x) => {
let (committed, _) = *n_parser_cache.as_ref().unwrap();
*n_parser_cache = None;
if committed {
CommitErr(x.error)
} else {
PeekErr(x)
}
}
CommitErr(x) => CommitErr(x),
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
self.0.add_error(errors);
}
}
/// Equivalent to [`p.then(f)`].
///
/// [`p.then(f)`]: ../trait.Parser.html#method.then
pub fn then<Input, P, F, N>(p: P, f: F) -> Then<P, F>
where
Input: Stream,
F: FnMut(P::Output) -> N,
P: Parser<Input>,
N: Parser<Input>,
{
Then(p, f)
}
#[derive(Copy, Clone)]
pub struct ThenPartial<P, F>(P, F);
impl<Input, P, N, F> Parser<Input> for ThenPartial<P, F>
where
Input: Stream,
F: FnMut(&mut P::Output) -> N,
P: Parser<Input>,
N: Parser<Input>,
{
type Output = N::Output;
type PartialState = (P::PartialState, Option<(bool, P::Output)>, N::PartialState);
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mut mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
if mode.is_first() || n_parser_cache.is_none() {
debug_assert!(n_parser_cache.is_none());
match self.0.parse_mode(mode, input, p_state) {
PeekOk(value) => {
*n_parser_cache = Some((false, value));
}
CommitOk(value) => {
*n_parser_cache = Some((true, value));
}
PeekErr(err) => return PeekErr(err),
CommitErr(err) => return CommitErr(err),
}
mode.set_first();
}
let result = (self.1)(&mut n_parser_cache.as_mut().unwrap().1)
.parse_committed_mode(mode, input, n_state);
match result {
PeekOk(x) => {
let (committed, _) = n_parser_cache.take().unwrap();
if committed {
CommitOk(x)
} else {
PeekOk(x)
}
}
CommitOk(x) => {
*n_parser_cache = None;
CommitOk(x)
}
PeekErr(x) => {
let (committed, _) = n_parser_cache.take().unwrap();
if committed {
CommitErr(x.error)
} else {
PeekErr(x)
}
}
CommitErr(x) => CommitErr(x),
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
self.0.add_error(errors);
}
}
/// Equivalent to [`p.then_partial(f)`].
///
/// [`p.then_partial(f)`]: ../trait.Parser.html#method.then_partial
pub fn then_partial<Input, P, F, N>(p: P, f: F) -> ThenPartial<P, F>
where
Input: Stream,
F: FnMut(&mut P::Output) -> N,
P: Parser<Input>,
N: Parser<Input>,
{
ThenPartial(p, f)
}
#[cfg(all(feature = "std", test))]
mod tests {
use crate::parser::{token::any, EasyParser};
#[test]
fn sequence_single_parser() {
assert!((any(),).easy_parse("a").is_ok());
}
}
#[derive(Copy, Clone)]
pub struct ThenRef<P, F>(P, F);
impl<Input, P, N, F> Parser<Input> for ThenRef<P, F>
where
Input: Stream,
F: FnMut(&P::Output) -> N,
P: Parser<Input>,
N: Parser<Input>,
{
type Output = (P::Output, N::Output);
type PartialState = (
P::PartialState,
Option<(bool, P::Output, N)>,
N::PartialState,
);
parse_mode!(Input);
#[inline]
fn parse_mode_impl<M>(
&mut self,
mut mode: M,
input: &mut Input,
state: &mut Self::PartialState,
) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
where
M: ParseMode,
{
let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
if mode.is_first() || n_parser_cache.is_none() {
debug_assert!(n_parser_cache.is_none());
let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
PeekOk(value) => (value, false),
CommitOk(value) => (value, true),
PeekErr(err) => return PeekErr(err),
CommitErr(err) => return CommitErr(err),
};
let parser = (self.1)(&value);
*n_parser_cache = Some((committed, value, parser));
mode.set_first();
}
let result = n_parser_cache
.as_mut()
.unwrap()
.2
.parse_committed_mode(mode, input, n_state);
match result {
PeekOk(x) => {
let (committed, in_value, _) = n_parser_cache.take().unwrap();
if committed {
CommitOk((in_value, x))
} else {
PeekOk((in_value, x))
}
}
CommitOk(x) => {
let (_, in_value, _) = n_parser_cache.take().unwrap();
*n_parser_cache = None;
CommitOk((in_value, x))
}
PeekErr(x) => {
let (committed, _, _) = n_parser_cache.take().unwrap();
*n_parser_cache = None;
if committed {
CommitErr(x.error)
} else {
PeekErr(x)
}
}
CommitErr(x) => CommitErr(x),
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
self.0.add_error(errors);
}
}
/// Equivalent to [`p.then_ref(f)`].
///
/// [`p.then_ref(f)`]: ../trait.Parser.html#method.then
pub fn then_ref<Input, P, F, N>(p: P, f: F) -> ThenRef<P, F>
where
Input: Stream,
F: FnMut(&P::Output) -> N,
P: Parser<Input>,
N: Parser<Input>,
{
ThenRef(p, f)
}

700
vendor/combine/src/parser/token.rs vendored Normal file
View File

@@ -0,0 +1,700 @@
//! Parsers working with single stream items.
use crate::{
error::{
self, ErrorInfo, ParseError,
ParseResult::{self, *},
ResultExt, StreamError, Tracked,
},
lib::marker::PhantomData,
stream::{uncons, Stream, StreamOnce},
Parser,
};
#[derive(Copy, Clone)]
pub struct Any<Input>(PhantomData<fn(Input) -> Input>);
impl<Input> Parser<Input> for Any<Input>
where
Input: Stream,
{
type Output = Input::Token;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
uncons(input)
}
}
/// Parses any token.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// let mut char_parser = any();
/// assert_eq!(char_parser.parse("!").map(|x| x.0), Ok('!'));
/// assert!(char_parser.parse("").is_err());
/// let mut byte_parser = any();
/// assert_eq!(byte_parser.parse(&b"!"[..]).map(|x| x.0), Ok(b'!'));
/// assert!(byte_parser.parse(&b""[..]).is_err());
/// # }
/// ```
pub fn any<Input>() -> Any<Input>
where
Input: Stream,
{
Any(PhantomData)
}
#[derive(Copy, Clone)]
pub struct Satisfy<Input, P> {
predicate: P,
_marker: PhantomData<Input>,
}
fn satisfy_impl<Input, P, R>(input: &mut Input, mut predicate: P) -> ParseResult<R, Input::Error>
where
Input: Stream,
P: FnMut(Input::Token) -> Option<R>,
{
let position = input.position();
match uncons(input) {
PeekOk(c) | CommitOk(c) => match predicate(c) {
Some(c) => CommitOk(c),
None => PeekErr(Input::Error::empty(position).into()),
},
PeekErr(err) => PeekErr(err),
CommitErr(err) => CommitErr(err),
}
}
impl<Input, P> Parser<Input> for Satisfy<Input, P>
where
Input: Stream,
P: FnMut(Input::Token) -> bool,
{
type Output = Input::Token;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> {
satisfy_impl(input, |c| {
if (self.predicate)(c.clone()) {
Some(c)
} else {
None
}
})
}
}
/// Parses a token and succeeds depending on the result of `predicate`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// let mut parser = satisfy(|c| c == '!' || c == '?');
/// assert_eq!(parser.parse("!").map(|x| x.0), Ok('!'));
/// assert_eq!(parser.parse("?").map(|x| x.0), Ok('?'));
/// # }
/// ```
pub fn satisfy<Input, P>(predicate: P) -> Satisfy<Input, P>
where
Input: Stream,
P: FnMut(Input::Token) -> bool,
{
Satisfy {
predicate,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct SatisfyMap<Input, P> {
predicate: P,
_marker: PhantomData<Input>,
}
impl<Input, P, R> Parser<Input> for SatisfyMap<Input, P>
where
Input: Stream,
P: FnMut(Input::Token) -> Option<R>,
{
type Output = R;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> {
satisfy_impl(input, &mut self.predicate)
}
}
/// Parses a token and passes it to `predicate`. If `predicate` returns `Some` the parser succeeds
/// and returns the value inside the `Option`. If `predicate` returns `None` the parser fails
/// without consuming any input.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// #[derive(Debug, PartialEq)]
/// enum YesNo {
/// Yes,
/// No,
/// }
/// let mut parser = satisfy_map(|c| {
/// match c {
/// 'Y' => Some(YesNo::Yes),
/// 'N' => Some(YesNo::No),
/// _ => None,
/// }
/// });
/// assert_eq!(parser.parse("Y").map(|x| x.0), Ok(YesNo::Yes));
/// assert!(parser.parse("A").map(|x| x.0).is_err());
/// # }
/// ```
pub fn satisfy_map<Input, P, R>(predicate: P) -> SatisfyMap<Input, P>
where
Input: Stream,
P: FnMut(Input::Token) -> Option<R>,
{
SatisfyMap {
predicate,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct Token<Input>
where
Input: Stream,
Input::Token: PartialEq,
{
c: Input::Token,
_marker: PhantomData<Input>,
}
impl<Input> Parser<Input> for Token<Input>
where
Input: Stream,
Input::Token: PartialEq + Clone,
{
type Output = Input::Token;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
satisfy_impl(input, |c| if c == self.c { Some(c) } else { None })
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
errors.error.add_expected(error::Token(self.c.clone()));
}
}
/// Parses a character and succeeds if the character is equal to `c`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// let result = token('!')
/// .parse("!")
/// .map(|x| x.0);
/// assert_eq!(result, Ok('!'));
/// # }
/// ```
pub fn token<Input>(c: Input::Token) -> Token<Input>
where
Input: Stream,
Input::Token: PartialEq,
{
Token {
c,
_marker: PhantomData,
}
}
#[derive(Clone)]
pub struct Tokens<C, E, T, Input>
where
Input: Stream,
{
cmp: C,
expected: E,
tokens: T,
_marker: PhantomData<Input>,
}
impl<Input, C, E, T> Parser<Input> for Tokens<C, E, T, Input>
where
C: FnMut(T::Item, Input::Token) -> bool,
E: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
T: Clone + IntoIterator,
Input: Stream,
{
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, Input::Error> {
let start = input.position();
let mut committed = false;
for c in self.tokens.clone() {
match crate::stream::uncons(input) {
CommitOk(other) | PeekOk(other) => {
if !(self.cmp)(c, other.clone()) {
return if committed {
let mut errors = <Input as StreamOnce>::Error::from_error(
start,
StreamError::unexpected_token(other),
);
errors.add_expected(&self.expected);
CommitErr(errors)
} else {
PeekErr(<Input as StreamOnce>::Error::empty(start).into())
};
}
committed = true;
}
PeekErr(mut error) => {
error.error.set_position(start);
return if committed {
CommitErr(error.error)
} else {
PeekErr(error)
};
}
CommitErr(mut error) => {
error.set_position(start);
return CommitErr(error);
}
}
}
if committed {
CommitOk(self.tokens.clone())
} else {
PeekOk(self.tokens.clone())
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
errors.error.add_expected(&self.expected);
}
}
/// Parses multiple tokens.
///
/// Consumes items from the input and compares them to the values from `tokens` using the
/// comparison function `cmp`. Succeeds if all the items from `tokens` are matched in the input
/// stream and fails otherwise with `expected` used as part of the error.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::error;
/// # fn main() {
/// let result = tokens(|l, r| l.eq_ignore_ascii_case(&r), "abc", "abc".chars())
/// .parse("AbC")
/// .map(|x| x.0.as_str());
/// assert_eq!(result, Ok("abc"));
/// let result = tokens(
/// |&l, r| (if l < r { r - l } else { l - r }) <= 2,
/// error::Range(&b"025"[..]),
/// &b"025"[..]
/// )
/// .parse(&b"123"[..])
/// .map(|x| x.0);
/// assert_eq!(result, Ok(&b"025"[..]));
/// # }
/// ```
pub fn tokens<C, E, T, Input>(cmp: C, expected: E, tokens: T) -> Tokens<C, E, T, Input>
where
C: FnMut(T::Item, Input::Token) -> bool,
T: Clone + IntoIterator,
Input: Stream,
{
Tokens {
cmp,
expected,
tokens,
_marker: PhantomData,
}
}
#[derive(Clone)]
pub struct TokensCmp<C, T, Input>
where
Input: Stream,
{
cmp: C,
tokens: T,
_marker: PhantomData<Input>,
}
impl<Input, C, T> Parser<Input> for TokensCmp<C, T, Input>
where
C: FnMut(T::Item, Input::Token) -> bool,
T: Clone + IntoIterator,
Input: Stream,
{
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, Input::Error> {
let start = input.position();
let mut committed = false;
for c in self.tokens.clone() {
match crate::stream::uncons(input) {
CommitOk(other) | PeekOk(other) => {
if !(self.cmp)(c, other.clone()) {
return if committed {
let errors = <Input as StreamOnce>::Error::from_error(
start,
StreamError::unexpected_token(other),
);
CommitErr(errors)
} else {
PeekErr(<Input as StreamOnce>::Error::empty(start).into())
};
}
committed = true;
}
PeekErr(mut error) => {
error.error.set_position(start);
return if committed {
CommitErr(error.error)
} else {
PeekErr(error)
};
}
CommitErr(mut error) => {
error.set_position(start);
return CommitErr(error);
}
}
}
if committed {
CommitOk(self.tokens.clone())
} else {
PeekOk(self.tokens.clone())
}
}
}
/// Parses multiple tokens.
///
/// Consumes items from the input and compares them to the values from `tokens` using the
/// comparison function `cmp`. Succeeds if all the items from `tokens` are matched in the input
/// stream and fails otherwise.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// # #[allow(deprecated)]
/// # use std::ascii::AsciiExt;
/// let result = tokens_cmp("abc".chars(), |l, r| l.eq_ignore_ascii_case(&r))
/// .parse("AbC")
/// .map(|x| x.0.as_str());
/// assert_eq!(result, Ok("abc"));
/// let result = tokens_cmp(
/// &b"025"[..],
/// |&l, r| (if l < r { r - l } else { l - r }) <= 2,
/// )
/// .parse(&b"123"[..])
/// .map(|x| x.0);
/// assert_eq!(result, Ok(&b"025"[..]));
/// # }
/// ```
pub fn tokens_cmp<C, T, I>(tokens: T, cmp: C) -> TokensCmp<C, T, I>
where
C: FnMut(T::Item, I::Token) -> bool,
T: Clone + IntoIterator,
I: Stream,
{
TokensCmp {
cmp,
tokens,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct Position<Input>
where
Input: Stream,
{
_marker: PhantomData<Input>,
}
impl<Input> Parser<Input> for Position<Input>
where
Input: Stream,
{
type Output = Input::Position;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Position, Input::Error> {
PeekOk(input.position())
}
}
/// Parser which just returns the current position in the stream.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::position::{self, SourcePosition};
/// # fn main() {
/// let result = (position(), token('!'), position())
/// .parse(position::Stream::new("!"))
/// .map(|x| x.0);
/// assert_eq!(result, Ok((SourcePosition { line: 1, column: 1 },
/// '!',
/// SourcePosition { line: 1, column: 2 })));
/// # }
/// ```
pub fn position<Input>() -> Position<Input>
where
Input: Stream,
{
Position {
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct OneOf<T, Input>
where
Input: Stream,
{
tokens: T,
_marker: PhantomData<Input>,
}
impl<Input, T> Parser<Input> for OneOf<T, Input>
where
T: Clone + IntoIterator<Item = Input::Token>,
Input: Stream,
Input::Token: PartialEq,
{
type Output = Input::Token;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
satisfy(|c| self.tokens.clone().into_iter().any(|t| t == c)).parse_lazy(input)
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
for expected in self.tokens.clone() {
errors.error.add_expected(error::Token(expected));
}
}
}
/// Extract one token and succeeds if it is part of `tokens`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// let result = many(one_of("abc".chars()))
/// .parse("abd");
/// assert_eq!(result, Ok((String::from("ab"), "d")));
/// # }
/// ```
pub fn one_of<T, Input>(tokens: T) -> OneOf<T, Input>
where
T: Clone + IntoIterator,
Input: Stream,
Input::Token: PartialEq<T::Item>,
{
OneOf {
tokens,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct NoneOf<T, Input>
where
Input: Stream,
{
tokens: T,
_marker: PhantomData<Input>,
}
impl<Input, T> Parser<Input> for NoneOf<T, Input>
where
T: Clone + IntoIterator<Item = Input::Token>,
Input: Stream,
Input::Token: PartialEq,
{
type Output = Input::Token;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
satisfy(|c| self.tokens.clone().into_iter().all(|t| t != c)).parse_lazy(input)
}
}
/// Extract one token and succeeds if it is not part of `tokens`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::easy;
/// # use combine::stream::position;
/// # fn main() {
/// let mut parser = many1(none_of(b"abc".iter().cloned()));
/// let result = parser.easy_parse(position::Stream::new(&b"xyb"[..]))
/// .map(|(output, input)| (output, input.input));
/// assert_eq!(result, Ok((b"xy"[..].to_owned(), &b"b"[..])));
///
/// let result = parser.easy_parse(position::Stream::new(&b"ab"[..]));
/// assert_eq!(result, Err(easy::Errors {
/// position: 0,
/// errors: vec![
/// easy::Error::Unexpected(easy::Info::Token(b'a')),
/// ]
/// }));
/// # }
/// ```
pub fn none_of<T, Input>(tokens: T) -> NoneOf<T, Input>
where
T: Clone + IntoIterator,
Input: Stream,
Input::Token: PartialEq<T::Item>,
{
NoneOf {
tokens,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct Value<Input, T>(T, PhantomData<fn(Input) -> Input>);
impl<Input, T> Parser<Input> for Value<Input, T>
where
Input: Stream,
T: Clone,
{
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, _: &mut Input) -> ParseResult<T, Input::Error> {
PeekOk(self.0.clone())
}
}
/// Always returns the value `v` without consuming any input.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # fn main() {
/// let result = value(42)
/// .parse("hello world")
/// .map(|x| x.0);
/// assert_eq!(result, Ok(42));
/// # }
/// ```
pub fn value<Input, T>(v: T) -> Value<Input, T>
where
Input: Stream,
T: Clone,
{
Value(v, PhantomData)
}
#[derive(Copy, Clone)]
pub struct Produce<Input, F>(F, PhantomData<fn(Input) -> Input>);
impl<Input, F, R> Parser<Input> for Produce<Input, F>
where
Input: Stream,
F: FnMut() -> R,
{
type Output = R;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, _: &mut Input) -> ParseResult<R, Input::Error> {
PeekOk((self.0)())
}
}
/// Always returns the value produced by calling `f`.
///
/// Can be used when `value` is unable to be used for lack of `Clone` implementation on the value.
///
/// ```
/// # use combine::*;
/// #[derive(Debug, PartialEq)]
/// struct NoClone;
/// let result = produce(|| vec![NoClone])
/// .parse("hello world")
/// .map(|x| x.0);
/// assert_eq!(result, Ok(vec![NoClone]));
/// ```
pub fn produce<Input, F, R>(f: F) -> Produce<Input, F>
where
Input: Stream,
F: FnMut() -> R,
{
Produce(f, PhantomData)
}
#[derive(Copy, Clone)]
pub struct Eof<Input>(PhantomData<Input>);
impl<Input> Parser<Input> for Eof<Input>
where
Input: Stream,
{
type Output = ();
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<(), Input::Error> {
let before = input.checkpoint();
match input.uncons() {
Err(ref err) if err.is_unexpected_end_of_input() => PeekOk(()),
_ => {
ctry!(input.reset(before).committed());
PeekErr(<Input as StreamOnce>::Error::empty(input.position()).into())
}
}
}
fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
errors.error.add_expected("end of input");
}
}
/// Succeeds only if the stream is at end of input, fails otherwise.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::easy;
/// # use combine::stream::position::{self, SourcePosition};
/// # fn main() {
/// let mut parser = eof();
/// assert_eq!(parser.easy_parse(position::Stream::new("")), Ok(((), position::Stream::new(""))));
/// assert_eq!(parser.easy_parse(position::Stream::new("x")), Err(easy::Errors {
/// position: SourcePosition::default(),
/// errors: vec![
/// easy::Error::Unexpected('x'.into()),
/// easy::Error::Expected("end of input".into())
/// ]
/// }));
/// # }
/// ```
pub fn eof<Input>() -> Eof<Input>
where
Input: Stream,
{
Eof(PhantomData)
}

942
vendor/combine/src/stream/buf_reader.rs vendored Normal file
View File

@@ -0,0 +1,942 @@
use std::io::{self, BufRead, Read};
#[cfg(any(
feature = "futures-03",
feature = "tokio-02",
feature = "tokio-03",
feature = "tokio"
))]
use std::pin::Pin;
#[cfg(any(feature = "futures-03", feature = "tokio-02", feature = "tokio-03"))]
use std::mem::MaybeUninit;
#[cfg(feature = "futures-core-03")]
use std::task::{Context, Poll};
#[cfg(feature = "futures-03")]
use std::future::Future;
use bytes::{Buf, BufMut, BytesMut};
#[cfg(feature = "pin-project-lite")]
use pin_project_lite::pin_project;
#[cfg(feature = "tokio-03")]
use tokio_03_dep::io::AsyncBufRead as _;
#[cfg(feature = "tokio")]
use tokio_dep::io::AsyncBufRead as _;
#[cfg(feature = "futures-core-03")]
use futures_core_03::ready;
#[cfg(feature = "pin-project-lite")]
pin_project! {
/// `BufReader` used by `Decoder` when it is constructed with [`Decoder::new_bufferless`][]
///
/// [`Decoder::new_bufferless`]: ../decoder/struct.Decoder.html#method.new_bufferless
#[derive(Debug)]
pub struct BufReader<R> {
#[pin]
inner: R,
buf: BytesMut
}
}
#[cfg(not(feature = "pin-project-lite"))]
/// `BufReader` used by `Decoder` when it is constructed with [`Decoder::new_bufferless`][]
///
/// [`Decoder::new_bufferless`]: ../decoder/struct.Decoder.html#method.new_bufferless
#[derive(Debug)]
pub struct BufReader<R> {
inner: R,
buf: BytesMut,
}
impl<R> BufReader<R> {
/// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB,
/// but may change in the future.
pub fn new(inner: R) -> Self {
Self::with_capacity(8096, inner)
}
/// Creates a new `BufReader` with the specified buffer capacity.
pub fn with_capacity(capacity: usize, inner: R) -> Self {
let buf = BytesMut::with_capacity(capacity);
Self { inner, buf }
}
/// Gets a reference to the underlying reader.
///
/// It is inadvisable to directly read from the underlying reader.
pub fn get_ref(&self) -> &R {
&self.inner
}
/// Gets a mutable reference to the underlying reader.
///
/// It is inadvisable to directly read from the underlying reader.
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
#[cfg(feature = "pin-project-lite")]
/// Gets a pinned mutable reference to the underlying reader.
///
/// It is inadvisable to directly read from the underlying reader.
pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut R> {
self.project().inner
}
/// Consumes this `BufWriter`, returning the underlying reader.
///
/// Note that any leftover data in the internal buffer is lost.
pub fn into_inner(self) -> R {
self.inner
}
/// Returns a reference to the internally buffered data.
///
/// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty.
pub fn buffer(&self) -> &[u8] {
&self.buf
}
/// Invalidates all data in the internal buffer.
#[inline]
#[cfg(any(feature = "tokio-02", feature = "tokio-03", feature = "tokio"))]
fn discard_buffer(self: Pin<&mut Self>) {
let me = self.project();
me.buf.clear();
}
}
mod sealed {
pub trait Sealed {}
}
#[doc(hidden)]
pub trait CombineBuffer<R>: sealed::Sealed {
fn buffer<'a>(&'a self, read: &'a R) -> &'a [u8];
fn advance(&mut self, read: &mut R, len: usize);
#[cfg(feature = "pin-project-lite")]
fn advance_pin(&mut self, read: Pin<&mut R>, len: usize);
}
#[doc(hidden)]
pub trait CombineSyncRead<R>: CombineBuffer<R> {
fn extend_buf_sync(&mut self, read: &mut R) -> io::Result<usize>;
}
#[cfg(any(feature = "tokio-02", feature = "tokio-03", feature = "tokio"))]
#[doc(hidden)]
pub trait CombineRead<R, T: ?Sized>: CombineBuffer<R> {
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>>;
}
#[cfg(feature = "futures-03")]
#[doc(hidden)]
pub trait CombineAsyncRead<R>: CombineBuffer<R> {
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>>;
fn extend_buf<'a>(&'a mut self, read: Pin<&'a mut R>) -> ExtendBuf<'a, Self, R>
where
Self: Sized;
}
#[cfg(feature = "futures-03")]
pin_project_lite::pin_project! {
#[doc(hidden)]
pub struct ExtendBuf<'a, C, R> {
buffer: &'a mut C,
read: Pin<&'a mut R>
}
}
#[cfg(feature = "futures-03")]
impl<'a, C, R> Future for ExtendBuf<'a, C, R>
where
C: CombineAsyncRead<R>,
{
type Output = io::Result<usize>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let me = self.project();
me.buffer.poll_extend_buf(cx, me.read.as_mut())
}
}
/// Marker used by `Decoder` for an internal buffer
#[derive(Default)]
pub struct Buffer(pub(crate) BytesMut);
impl sealed::Sealed for Buffer {}
impl<R> CombineBuffer<R> for Buffer {
fn buffer<'a>(&'a self, _read: &'a R) -> &'a [u8] {
&self.0
}
fn advance(&mut self, _read: &mut R, len: usize) {
self.0.advance(len);
}
#[cfg(feature = "pin-project-lite")]
fn advance_pin(&mut self, _read: Pin<&mut R>, len: usize) {
self.0.advance(len);
}
}
impl<R> CombineSyncRead<R> for Buffer
where
R: Read,
{
fn extend_buf_sync(&mut self, read: &mut R) -> io::Result<usize> {
extend_buf_sync(&mut self.0, read)
}
}
#[cfg(feature = "futures-03")]
impl<R> CombineAsyncRead<R> for Buffer
where
R: futures_io_03::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>> {
poll_extend_buf(&mut self.0, cx, read)
}
fn extend_buf<'a>(&'a mut self, read: Pin<&'a mut R>) -> ExtendBuf<'a, Self, R> {
if !self.0.has_remaining_mut() {
self.0.reserve(8 * 1024);
}
// Copy of tokio's read_buf method (but it has to force initialize the buffer)
let bs = self.0.chunk_mut();
for i in 0..bs.len() {
bs.write_byte(i, 0);
}
ExtendBuf { buffer: self, read }
}
}
#[cfg(feature = "tokio-02")]
impl<R> CombineRead<R, dyn tokio_02_dep::io::AsyncRead> for Buffer
where
R: tokio_02_dep::io::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>> {
if !self.0.has_remaining_mut() {
self.0.reserve(8 * 1024);
}
read.poll_read_buf(cx, &mut Bytes05(&mut self.0))
}
}
#[cfg(feature = "tokio-03")]
fn tokio_03_to_read_buf(bs: &mut BytesMut) -> tokio_03_dep::io::ReadBuf<'_> {
let uninit = bs.chunk_mut();
unsafe {
tokio_03_dep::io::ReadBuf::uninit(std::slice::from_raw_parts_mut(
uninit.as_mut_ptr() as *mut MaybeUninit<u8>,
uninit.len(),
))
}
}
#[cfg(feature = "tokio-03")]
impl<R> CombineRead<R, dyn tokio_03_dep::io::AsyncRead> for Buffer
where
R: tokio_03_dep::io::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>> {
tokio_03_read_buf(cx, read, &mut self.0)
}
}
#[cfg(feature = "tokio-03")]
fn tokio_03_read_buf(
cx: &mut Context<'_>,
read: Pin<&mut impl tokio_03_dep::io::AsyncRead>,
bs: &mut bytes::BytesMut,
) -> Poll<io::Result<usize>> {
if !bs.has_remaining_mut() {
bs.reserve(8 * 1024);
}
let mut buf = tokio_03_to_read_buf(bs);
ready!(read.poll_read(cx, &mut buf))?;
unsafe {
let n = buf.filled().len();
bs.advance_mut(n);
Poll::Ready(Ok(n))
}
}
#[cfg(feature = "tokio")]
impl<R> CombineRead<R, dyn tokio_dep::io::AsyncRead> for Buffer
where
R: tokio_dep::io::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>> {
tokio_read_buf(read, cx, &mut self.0)
}
}
#[cfg(feature = "tokio")]
fn tokio_read_buf(
read: Pin<&mut impl tokio_dep::io::AsyncRead>,
cx: &mut Context<'_>,
bs: &mut bytes::BytesMut,
) -> Poll<io::Result<usize>> {
if !bs.has_remaining_mut() {
bs.reserve(8 * 1024);
}
tokio_util::io::poll_read_buf(read, cx, bs)
}
/// Marker used by `Decoder` for an external buffer
#[derive(Default)]
pub struct Bufferless;
impl sealed::Sealed for Bufferless {}
impl<R> CombineBuffer<BufReader<R>> for Bufferless {
fn buffer<'a>(&'a self, read: &'a BufReader<R>) -> &'a [u8] {
&read.buf
}
fn advance(&mut self, read: &mut BufReader<R>, len: usize) {
read.buf.advance(len);
}
#[cfg(feature = "pin-project-lite")]
fn advance_pin(&mut self, read: Pin<&mut BufReader<R>>, len: usize) {
read.project().buf.advance(len);
}
}
impl<R> CombineSyncRead<BufReader<R>> for Bufferless
where
R: Read,
{
fn extend_buf_sync(&mut self, read: &mut BufReader<R>) -> io::Result<usize> {
extend_buf_sync(&mut read.buf, &mut read.inner)
}
}
fn extend_buf_sync<R>(buf: &mut BytesMut, read: &mut R) -> io::Result<usize>
where
R: Read,
{
let size = 8 * 1024;
if !buf.has_remaining_mut() {
buf.reserve(size);
}
// Copy of tokio's poll_read_buf method (but it has to force initialize the buffer)
let n = {
let bs = buf.chunk_mut();
let initial_size = bs.len().min(size);
let bs = &mut bs[..initial_size];
for i in 0..bs.len() {
bs.write_byte(i, 0);
}
// Convert to `&mut [u8]`
// SAFETY: the entire buffer is preinitialized above
let bs = unsafe { &mut *(bs as *mut _ as *mut [u8]) };
let n = read.read(bs)?;
assert!(
n <= bs.len(),
"AsyncRead reported that it initialized more than the number of bytes in the buffer"
);
n
};
// SAFETY: the entire buffer has been preinitialized
unsafe { buf.advance_mut(n) };
Ok(n)
}
#[cfg(feature = "tokio-02")]
struct Bytes05<'a>(&'a mut BytesMut);
#[cfg(feature = "tokio-02")]
impl bytes_05::BufMut for Bytes05<'_> {
fn remaining_mut(&self) -> usize {
self.0.remaining_mut()
}
unsafe fn advance_mut(&mut self, cnt: usize) {
self.0.advance_mut(cnt)
}
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
unsafe { &mut *(self.0.chunk_mut() as *mut _ as *mut [MaybeUninit<u8>]) }
}
}
#[cfg(feature = "tokio-02")]
impl<R> CombineRead<BufReader<R>, dyn tokio_02_dep::io::AsyncRead> for Bufferless
where
R: tokio_02_dep::io::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut BufReader<R>>,
) -> Poll<io::Result<usize>> {
let me = read.project();
if !me.buf.has_remaining_mut() {
me.buf.reserve(8 * 1024);
}
tokio_02_dep::io::AsyncRead::poll_read_buf(me.inner, cx, &mut Bytes05(me.buf))
}
}
#[cfg(feature = "tokio-03")]
impl<R> CombineRead<BufReader<R>, dyn tokio_03_dep::io::AsyncRead> for Bufferless
where
R: tokio_03_dep::io::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut BufReader<R>>,
) -> Poll<io::Result<usize>> {
let me = read.project();
tokio_03_read_buf(cx, me.inner, me.buf)
}
}
#[cfg(feature = "tokio")]
impl<R> CombineRead<BufReader<R>, dyn tokio_dep::io::AsyncRead> for Bufferless
where
R: tokio_dep::io::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut BufReader<R>>,
) -> Poll<io::Result<usize>> {
let me = read.project();
tokio_read_buf(me.inner, cx, me.buf)
}
}
#[cfg(feature = "futures-03")]
impl<R> CombineAsyncRead<BufReader<R>> for Bufferless
where
R: futures_io_03::AsyncRead,
{
fn poll_extend_buf(
&mut self,
cx: &mut Context<'_>,
read: Pin<&mut BufReader<R>>,
) -> Poll<io::Result<usize>> {
let me = read.project();
poll_extend_buf(me.buf, cx, me.inner)
}
fn extend_buf<'a>(
&'a mut self,
mut read: Pin<&'a mut BufReader<R>>,
) -> ExtendBuf<'a, Self, BufReader<R>> {
let me = read.as_mut().project();
if !me.buf.has_remaining_mut() {
me.buf.reserve(8 * 1024);
}
// Copy of tokio's read_buf method (but it has to force initialize the buffer)
let bs = me.buf.chunk_mut();
for i in 0..bs.len() {
bs.write_byte(i, 0);
}
ExtendBuf { buffer: self, read }
}
}
#[cfg(feature = "futures-03")]
fn poll_extend_buf<R>(
buf: &mut BytesMut,
cx: &mut Context<'_>,
read: Pin<&mut R>,
) -> Poll<io::Result<usize>>
where
R: futures_io_03::AsyncRead,
{
// Copy of tokio's read_buf method (but it has to force initialize the buffer)
let n = {
let bs = buf.chunk_mut();
// preinit the buffer
for i in 0..bs.len() {
bs.write_byte(i, 0);
}
// Convert to `&mut [u8]`
// SAFETY: preinitialize the buffer
let bs = unsafe { &mut *(bs as *mut _ as *mut [u8]) };
let n = ready!(read.poll_read(cx, bs))?;
assert!(
n <= bs.len(),
"AsyncRead reported that it initialized more than the number of bytes in the buffer"
);
n
};
// SAFETY: the buffer was preinitialized
unsafe { buf.advance_mut(n) };
Poll::Ready(Ok(n))
}
#[cfg(feature = "tokio-02")]
impl<R: tokio_02_dep::io::AsyncRead> tokio_02_dep::io::AsyncRead for BufReader<R> {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
use tokio_02_dep::io::AsyncBufRead;
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if !self.buf.has_remaining_mut() && buf.len() >= self.buf.len() {
let res = ready!(self.as_mut().get_pin_mut().poll_read(cx, buf));
self.discard_buffer();
return Poll::Ready(res);
}
let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?;
let nread = rem.read(buf)?;
self.consume(nread);
Poll::Ready(Ok(nread))
}
// we can't skip unconditionally because of the large buffer case in read.
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [MaybeUninit<u8>]) -> bool {
self.inner.prepare_uninitialized_buffer(buf)
}
}
#[cfg(feature = "tokio-02")]
impl<R: tokio_02_dep::io::AsyncRead> tokio_02_dep::io::AsyncBufRead for BufReader<R> {
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
let me = self.project();
// If we've reached the end of our internal buffer then we need to fetch
// some more data from the underlying reader.
// Branch using `>=` instead of the more correct `==`
// to tell the compiler that the pos..cap slice is always valid.
if me.buf.is_empty() {
ready!(me.inner.poll_read_buf(cx, &mut Bytes05(me.buf)))?;
}
Poll::Ready(Ok(&me.buf[..]))
}
fn consume(self: Pin<&mut Self>, amt: usize) {
let me = self.project();
me.buf.advance(amt);
}
}
#[cfg(feature = "tokio-02")]
impl<R: tokio_02_dep::io::AsyncRead + tokio_02_dep::io::AsyncWrite> tokio_02_dep::io::AsyncWrite
for BufReader<R>
{
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.get_pin_mut().poll_write(cx, buf)
}
fn poll_write_buf<B: bytes_05::Buf>(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut B,
) -> Poll<io::Result<usize>> {
self.get_pin_mut().poll_write_buf(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.get_pin_mut().poll_flush(cx)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.get_pin_mut().poll_shutdown(cx)
}
}
#[cfg(feature = "tokio-03")]
impl<R: tokio_03_dep::io::AsyncRead> tokio_03_dep::io::AsyncRead for BufReader<R> {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut tokio_03_dep::io::ReadBuf<'_>,
) -> Poll<io::Result<()>> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if !self.buf.has_remaining_mut() && buf.remaining() >= self.buf.len() {
let res = ready!(self.as_mut().get_pin_mut().poll_read(cx, buf));
self.discard_buffer();
return Poll::Ready(res);
}
let rem = ready!(self.as_mut().poll_fill_buf(cx))?;
let amt = std::cmp::min(rem.len(), buf.remaining());
buf.put_slice(&rem[..amt]);
self.consume(amt);
Poll::Ready(Ok(()))
}
}
#[cfg(feature = "tokio-03")]
impl<R: tokio_03_dep::io::AsyncRead> tokio_03_dep::io::AsyncBufRead for BufReader<R> {
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
let me = self.project();
// If we've reached the end of our internal buffer then we need to fetch
// some more data from the underlying reader.
if me.buf.is_empty() {
ready!(tokio_03_read_buf(cx, me.inner, me.buf))?;
}
Poll::Ready(Ok(&me.buf[..]))
}
fn consume(self: Pin<&mut Self>, amt: usize) {
let me = self.project();
me.buf.advance(amt);
}
}
#[cfg(feature = "tokio-03")]
impl<R: tokio_03_dep::io::AsyncRead + tokio_03_dep::io::AsyncWrite> tokio_03_dep::io::AsyncWrite
for BufReader<R>
{
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.get_pin_mut().poll_write(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.get_pin_mut().poll_flush(cx)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.get_pin_mut().poll_shutdown(cx)
}
}
#[cfg(feature = "tokio")]
impl<R: tokio_dep::io::AsyncRead> tokio_dep::io::AsyncRead for BufReader<R> {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut tokio_dep::io::ReadBuf<'_>,
) -> Poll<io::Result<()>> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if !self.buf.has_remaining_mut() && buf.remaining() >= self.buf.len() {
let res = ready!(self.as_mut().get_pin_mut().poll_read(cx, buf));
self.discard_buffer();
return Poll::Ready(res);
}
let rem = ready!(self.as_mut().poll_fill_buf(cx))?;
let amt = std::cmp::min(rem.len(), buf.remaining());
buf.put_slice(&rem[..amt]);
self.consume(amt);
Poll::Ready(Ok(()))
}
}
#[cfg(feature = "tokio")]
impl<R: tokio_dep::io::AsyncRead> tokio_dep::io::AsyncBufRead for BufReader<R> {
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
let me = self.project();
// If we've reached the end of our internal buffer then we need to fetch
// some more data from the underlying reader.
if me.buf.is_empty() {
ready!(tokio_read_buf(me.inner, cx, me.buf))?;
}
Poll::Ready(Ok(&me.buf[..]))
}
fn consume(self: Pin<&mut Self>, amt: usize) {
let me = self.project();
me.buf.advance(amt);
}
}
#[cfg(feature = "tokio")]
impl<R: tokio_dep::io::AsyncRead + tokio_dep::io::AsyncWrite> tokio_dep::io::AsyncWrite
for BufReader<R>
{
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.get_pin_mut().poll_write(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.get_pin_mut().poll_flush(cx)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.get_pin_mut().poll_shutdown(cx)
}
}
impl<R: Read> Read for BufReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if !self.buf.has_remaining_mut() && buf.len() >= self.buf.len() {
let res = self.read(buf);
self.buf.clear();
return res;
}
let nread = {
let mut rem = self.fill_buf()?;
rem.read(buf)?
};
self.consume(nread);
Ok(nread)
}
}
impl<R: Read> BufRead for BufReader<R> {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
// If we've reached the end of our internal buffer then we need to fetch
// some more data from the underlying reader.
// Branch using `>=` instead of the more correct `==`
// to tell the compiler that the pos..cap slice is always valid.
if self.buf.is_empty() {
Bufferless.extend_buf_sync(self)?;
}
Ok(&self.buf[..])
}
fn consume(&mut self, amt: usize) {
self.buf.advance(amt);
}
}
#[cfg(test)]
#[cfg(feature = "tokio-02")]
mod tests {
use super::{BufReader, Bufferless, CombineRead};
use std::{io, pin::Pin};
use {
bytes_05::BytesMut,
tokio_02_dep::{
self as tokio,
io::{AsyncRead, AsyncReadExt},
},
};
impl<R: AsyncRead> BufReader<R> {
async fn extend_buf_tokio_02(mut self: Pin<&mut Self>) -> io::Result<usize> {
crate::future_ext::poll_fn(|cx| Bufferless.poll_extend_buf(cx, self.as_mut())).await
}
}
#[tokio::test]
async fn buf_reader() {
let mut read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
let mut buf = [0u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [1, 2, 3]);
let mut buf = [0u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [4, 5, 6]);
let mut buf = [0u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [7, 8, 9]);
let mut buf = [1u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [0, 1, 1]);
}
#[tokio::test]
async fn buf_reader_buf() {
let mut read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
let mut buf = BytesMut::with_capacity(3);
read.read_buf(&mut buf).await.unwrap();
assert_eq!(&buf[..], [1, 2, 3]);
read.read_buf(&mut buf).await.unwrap();
assert_eq!(&buf[..], [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
#[tokio::test]
async fn buf_reader_extend_buf() {
let read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
futures_03_dep::pin_mut!(read);
assert_eq!(read.as_mut().extend_buf_tokio_02().await.unwrap(), 3);
assert_eq!(read.buffer(), [1, 2, 3]);
assert_eq!(read.as_mut().extend_buf_tokio_02().await.unwrap(), 7);
assert_eq!(read.buffer(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
}
#[cfg(test)]
#[cfg(feature = "tokio")]
mod tests_tokio_1 {
use super::{BufReader, Bufferless, CombineRead};
use std::{io, pin::Pin};
use {
bytes::BytesMut,
tokio_dep::{
self as tokio,
io::{AsyncRead, AsyncReadExt},
},
};
impl<R: AsyncRead> BufReader<R> {
async fn extend_buf_tokio(mut self: Pin<&mut Self>) -> io::Result<usize> {
crate::future_ext::poll_fn(|cx| Bufferless.poll_extend_buf(cx, self.as_mut())).await
}
}
#[tokio::test]
async fn buf_reader() {
let mut read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
let mut buf = [0u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [1, 2, 3]);
let mut buf = [0u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [4, 5, 6]);
let mut buf = [0u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [7, 8, 9]);
let mut buf = [1u8; 3];
read.read(&mut buf).await.unwrap();
assert_eq!(buf, [0, 1, 1]);
}
#[tokio::test]
async fn buf_reader_buf() {
let mut read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
let mut buf = BytesMut::with_capacity(3);
read.read_buf(&mut buf).await.unwrap();
assert_eq!(&buf[..], [1, 2, 3]);
read.read_buf(&mut buf).await.unwrap();
assert_eq!(&buf[..], [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
#[tokio::test]
async fn buf_reader_extend_buf() {
let read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
futures_03_dep::pin_mut!(read);
assert_eq!(read.as_mut().extend_buf_tokio().await.unwrap(), 3);
assert_eq!(read.buffer(), [1, 2, 3]);
assert_eq!(read.as_mut().extend_buf_tokio().await.unwrap(), 7);
assert_eq!(read.buffer(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
}
#[cfg(test)]
mod tests_sync {
use super::{BufReader, Bufferless, CombineSyncRead};
use std::io::Read;
#[test]
#[allow(clippy::unused_io_amount)]
fn buf_reader() {
let mut read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
let mut buf = [0u8; 3];
read.read(&mut buf).unwrap();
assert_eq!(buf, [1, 2, 3]);
let mut buf = [0u8; 3];
read.read(&mut buf).unwrap();
assert_eq!(buf, [4, 5, 6]);
let mut buf = [0u8; 3];
read.read(&mut buf).unwrap();
assert_eq!(buf, [7, 8, 9]);
let mut buf = [1u8; 3];
read.read(&mut buf).unwrap();
assert_eq!(buf, [0, 1, 1]);
}
#[test]
fn buf_reader_extend_buf() {
let mut read = BufReader::with_capacity(3, &[1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0][..]);
assert_eq!(Bufferless.extend_buf_sync(&mut read).unwrap(), 3);
assert_eq!(read.buffer(), [1, 2, 3]);
assert_eq!(Bufferless.extend_buf_sync(&mut read).unwrap(), 7);
assert_eq!(read.buffer(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
}

141
vendor/combine/src/stream/buffered.rs vendored Normal file
View File

@@ -0,0 +1,141 @@
use alloc::collections::VecDeque;
use crate::{
error::StreamError,
stream::{ParseError, Positioned, ResetStream, StreamErrorFor, StreamOnce},
};
/// `Stream` which buffers items from an instance of `StreamOnce` into a ring buffer.
/// Instances of `StreamOnce` which is not able to implement `ResetStream` (such as `ReadStream`) may
/// use this as a way to implement `ResetStream` and become a full `Stream` instance.
///
/// The drawback is that the buffer only stores a limited number of items which limits how many
/// tokens that can be reset and replayed. If a `buffered::Stream` is reset past this limit an error
/// will be returned when `uncons` is next called.
///
/// NOTE: If this stream is used in conjunction with an error enhancing stream such as
/// `easy::Stream` (also via the `easy_parser` method) it is recommended that the `buffered::Stream`
/// instance wraps the `easy::Stream` instance instead of the other way around.
///
/// ```ignore
/// // DO
/// buffered::Stream::new(easy::Stream(..), ..)
/// // DON'T
/// easy::Stream(buffered::Stream::new(.., ..))
/// parser.easy_parse(buffered::Stream::new(..));
/// ```
#[derive(Debug, PartialEq)]
pub struct Stream<Input>
where
Input: StreamOnce + Positioned,
{
offset: usize,
iter: Input,
buffer_offset: usize,
buffer: VecDeque<(Input::Token, Input::Position)>,
}
impl<Input> ResetStream for Stream<Input>
where
Input: Positioned,
{
type Checkpoint = usize;
fn checkpoint(&self) -> Self::Checkpoint {
self.offset
}
fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
if checkpoint < self.buffer_offset - self.buffer.len() {
// We have backtracked to far
Err(Self::Error::from_error(
self.position(),
StreamErrorFor::<Self>::message_static_message("Backtracked to far"),
))
} else {
self.offset = checkpoint;
Ok(())
}
}
}
impl<Input> Stream<Input>
where
Input: StreamOnce + Positioned,
Input::Position: Clone,
Input::Token: Clone,
{
/// Constructs a new `BufferedStream` from a `StreamOnce` instance with a `lookahead`
/// number of elements that can be stored in the buffer.
pub fn new(iter: Input, lookahead: usize) -> Stream<Input> {
Stream {
offset: 0,
iter,
buffer_offset: 0,
buffer: VecDeque::with_capacity(lookahead),
}
}
}
impl<Input> Positioned for Stream<Input>
where
Input: StreamOnce + Positioned,
{
#[inline]
fn position(&self) -> Self::Position {
if self.offset >= self.buffer_offset {
self.iter.position()
} else if self.offset < self.buffer_offset - self.buffer.len() {
self.buffer
.front()
.expect("At least 1 element in the buffer")
.1
.clone()
} else {
self.buffer[self.buffer.len() - (self.buffer_offset - self.offset)]
.1
.clone()
}
}
}
impl<Input> StreamOnce for Stream<Input>
where
Input: StreamOnce + Positioned,
Input::Token: Clone,
{
type Token = Input::Token;
type Range = Input::Range;
type Position = Input::Position;
type Error = Input::Error;
#[inline]
fn uncons(&mut self) -> Result<Input::Token, StreamErrorFor<Self>> {
if self.offset >= self.buffer_offset {
let position = self.iter.position();
let token = self.iter.uncons()?;
self.buffer_offset += 1;
// We want the VecDeque to only keep the last .capacity() elements so we need to remove
// an element if it gets to large
if self.buffer.len() == self.buffer.capacity() {
self.buffer.pop_front();
}
self.buffer.push_back((token.clone(), position));
self.offset += 1;
Ok(token)
} else if self.offset < self.buffer_offset - self.buffer.len() {
// We have backtracked to far
Err(StreamError::message_static_message("Backtracked to far"))
} else {
let value = self.buffer[self.buffer.len() - (self.buffer_offset - self.offset)]
.0
.clone();
self.offset += 1;
Ok(value)
}
}
fn is_partial(&self) -> bool {
self.iter.is_partial()
}
}

227
vendor/combine/src/stream/decoder.rs vendored Normal file
View File

@@ -0,0 +1,227 @@
use crate::{
error::ParseError,
stream::buf_reader::{Buffer, Bufferless, CombineBuffer},
};
use std::{
fmt,
io::{self, Read},
};
#[cfg(feature = "pin-project-lite")]
use std::pin::Pin;
#[derive(Debug)]
pub enum Error<E, P> {
Parse(E),
Io { position: P, error: io::Error },
}
impl<'a, P> From<Error<crate::easy::Errors<u8, &'a [u8], P>, P>>
for crate::easy::Errors<u8, &'a [u8], P>
where
P: Ord + Clone,
{
fn from(e: Error<crate::easy::Errors<u8, &'a [u8], P>, P>) -> Self {
match e {
Error::Parse(e) => e,
Error::Io { position, error } => {
crate::easy::Errors::from_error(position, crate::easy::Error::Other(error.into()))
}
}
}
}
impl<E, P> std::error::Error for Error<E, P>
where
E: std::error::Error,
P: fmt::Display + fmt::Debug,
{
}
impl<E: fmt::Display, P: fmt::Display> fmt::Display for Error<E, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Parse(e) => e.fmt(f),
Error::Io { position: _, error } => error.fmt(f),
}
}
}
#[derive(Default)]
/// Used together with the `decode!` macro
pub struct Decoder<S, P, C = Buffer> {
position: P,
state: S,
buffer: C,
end_of_input: bool,
}
impl<S, P> Decoder<S, P, Buffer>
where
P: Default,
S: Default,
{
/// Constructs a new [`Decoder`] with an internal buffer. Allows any `AsyncRead/Read` instance to
/// be used when decoding but there may be data left in the internal buffer after decoding
/// (accessible with [`Decoder::buffer`])
pub fn new() -> Self {
Decoder::default()
}
/// Constructs a new [`Decoder`] with an internal buffer. Allows any `AsyncRead/Read` instance to
/// be used when decoding but there may be data left in the internal buffer after decoding
/// (accessible with [`Decoder::buffer`])
pub fn new_buffer() -> Self {
Decoder::new()
}
}
impl<S, P> Decoder<S, P, Bufferless>
where
P: Default,
S: Default,
{
/// Constructs a new `Decoder` without an internal buffer. Requires the read instance to be
/// wrapped with combine's [`BufReader`] instance to
///
/// [`BufReader`]: super::buf_reader::BufReader
pub fn new_bufferless() -> Self {
Decoder::default()
}
}
impl<S, P> Decoder<S, P> {
pub fn buffer(&self) -> &[u8] {
&self.buffer.0
}
}
impl<S, P, C> Decoder<S, P, C> {
#[doc(hidden)]
pub fn advance<R>(&mut self, read: &mut R, removed: usize)
where
C: CombineBuffer<R>,
{
// Remove the data we have parsed and adjust `removed` to be the amount of data we
// committed from `self.reader`
self.buffer.advance(read, removed)
}
#[doc(hidden)]
#[cfg(feature = "pin-project-lite")]
pub fn advance_pin<R>(&mut self, read: Pin<&mut R>, removed: usize)
where
C: CombineBuffer<R>,
{
// Remove the data we have parsed and adjust `removed` to be the amount of data we
// committed from `self.reader`
self.buffer.advance_pin(read, removed);
}
pub fn position(&self) -> &P {
&self.position
}
#[doc(hidden)]
pub fn __inner(&mut self) -> (&mut S, &mut P, &C, bool) {
(
&mut self.state,
&mut self.position,
&self.buffer,
self.end_of_input,
)
}
}
impl<S, P, C> Decoder<S, P, C>
where
C: ,
{
#[doc(hidden)]
pub fn __before_parse<R>(&mut self, mut reader: R) -> io::Result<()>
where
R: Read,
C: crate::stream::buf_reader::CombineSyncRead<R>,
{
if self.buffer.extend_buf_sync(&mut reader)? == 0 {
self.end_of_input = true;
}
Ok(())
}
}
#[cfg(feature = "tokio-02")]
impl<S, P, C> Decoder<S, P, C> {
#[doc(hidden)]
pub async fn __before_parse_tokio_02<R>(&mut self, mut reader: Pin<&mut R>) -> io::Result<()>
where
R: tokio_02_dep::io::AsyncRead,
C: crate::stream::buf_reader::CombineRead<R, dyn tokio_02_dep::io::AsyncRead>,
{
let copied =
crate::future_ext::poll_fn(|cx| self.buffer.poll_extend_buf(cx, reader.as_mut()))
.await?;
if copied == 0 {
self.end_of_input = true;
}
Ok(())
}
}
#[cfg(feature = "tokio-03")]
impl<S, P, C> Decoder<S, P, C> {
#[doc(hidden)]
pub async fn __before_parse_tokio_03<R>(&mut self, mut reader: Pin<&mut R>) -> io::Result<()>
where
R: tokio_03_dep::io::AsyncRead,
C: crate::stream::buf_reader::CombineRead<R, dyn tokio_03_dep::io::AsyncRead>,
{
let copied =
crate::future_ext::poll_fn(|cx| self.buffer.poll_extend_buf(cx, reader.as_mut()))
.await?;
if copied == 0 {
self.end_of_input = true;
}
Ok(())
}
}
#[cfg(feature = "tokio")]
impl<S, P, C> Decoder<S, P, C> {
#[doc(hidden)]
pub async fn __before_parse_tokio<R>(&mut self, mut reader: Pin<&mut R>) -> io::Result<()>
where
R: tokio_dep::io::AsyncRead,
C: crate::stream::buf_reader::CombineRead<R, dyn tokio_dep::io::AsyncRead>,
{
let copied =
crate::future_ext::poll_fn(|cx| self.buffer.poll_extend_buf(cx, reader.as_mut()))
.await?;
if copied == 0 {
self.end_of_input = true;
}
Ok(())
}
}
#[cfg(feature = "futures-03")]
impl<S, P, C> Decoder<S, P, C> {
#[doc(hidden)]
pub async fn __before_parse_async<R>(&mut self, reader: Pin<&mut R>) -> io::Result<()>
where
R: futures_io_03::AsyncRead,
C: crate::stream::buf_reader::CombineAsyncRead<R>,
{
let copied = self.buffer.extend_buf(reader).await?;
if copied == 0 {
self.end_of_input = true;
}
Ok(())
}
}

897
vendor/combine/src/stream/easy.rs vendored Normal file
View File

@@ -0,0 +1,897 @@
//! Stream wrapper which provides an informative and easy to use error type.
//!
//! Unless you have specific constraints preventing you from using this error type (such as being
//! a `no_std` environment) you probably want to use this stream type. It can easily be used
//! through the [`EasyParser::easy_parse`] method.
//!
//! The provided `Errors` type is roughly the same as `ParseError` in combine 1.x and 2.x.
//!
//! ```
//! #[macro_use]
//! extern crate combine;
//! use combine::{easy, Parser, EasyParser, Stream, many1};
//! use combine::parser::char::letter;
//! use combine::stream::StreamErrorFor;
//! use combine::error::{ParseError, StreamError};
//!
//! fn main() {
//! parser!{
//! fn parser[Input]()(Input) -> String
//! where [
//! Input: Stream<Token = char, Error = easy::ParseError<Input>>,
//! Input::Range: PartialEq,
//! // If we want to use the error type explicitly we need to help rustc infer
//! // `StreamError` to `easy::Error` (rust-lang/rust#24159)
//! Input::Error: ParseError<
//! Input::Token,
//! Input::Range,
//! Input::Position,
//! StreamError = easy::Error<Input::Token, Input::Range>
//! >
//! ]
//! {
//! many1(letter()).and_then(|word: String| {
//! if word == "combine" {
//! Ok(word)
//! } else {
//! Err(easy::Error::Expected(easy::Info::Static("combine")))
//! }
//! })
//! }
//! }
//!
//! parser!{
//! fn parser2[Input]()(Input) -> String
//! where [
//! Input: Stream<Token = char>,
//! ]
//! {
//! many1(letter()).and_then(|word: String| {
//! if word == "combine" {
//! Ok(word)
//! } else {
//! // Alternatively it is possible to only use the methods provided by the
//! // `StreamError` trait.
//! // In that case the extra bound is not necessary (and this method will work
//! // for other errors than `easy::Errors`)
//! Err(StreamErrorFor::<Input>::expected_static_message("combine"))
//! }
//! })
//! }
//! }
//!
//! let input = "combin";
//! let expected_error = Err(easy::Errors {
//! errors: vec![
//! easy::Error::Expected("combine".into())
//! ],
//! position: 0,
//! });
//! assert_eq!(
//! parser().easy_parse(input).map_err(|err| err.map_position(|p| p.translate_position(input))),
//! expected_error
//! );
//! assert_eq!(
//! parser2().easy_parse(input).map_err(|err| err.map_position(|p| p.translate_position(input))),
//! expected_error
//! );
//! }
//!
//! ```
//!
//! [`EasyParser::easy_parse`]: super::super::parser::EasyParser::easy_parse
use std::{error::Error as StdError, fmt};
use crate::error::{Info as PrimitiveInfo, ParseResult, StreamError, Tracked};
use crate::stream::{
Positioned, RangeStream, RangeStreamOnce, ResetStream, StreamErrorFor, StreamOnce,
};
/// Enum holding error information. Variants are defined for `Stream::Token` and `Stream::Range` as
/// well as string variants holding easy descriptions.
///
/// As there is implementations of `From` for `String` and `&'static str` the
/// constructor need not be used directly as calling `msg.into()` should turn a message into the
/// correct `Info` variant.
#[derive(Clone, Debug)]
pub enum Info<T, R> {
Token(T),
Range(R),
Owned(String),
Static(&'static str),
}
impl<T, R, F> From<PrimitiveInfo<T, R, F>> for Info<T, R>
where
F: fmt::Display,
{
fn from(info: PrimitiveInfo<T, R, F>) -> Self {
match info {
PrimitiveInfo::Token(b) => Info::Token(b),
PrimitiveInfo::Range(b) => Info::Range(b),
PrimitiveInfo::Static(b) => Info::Static(b),
PrimitiveInfo::Format(b) => Info::Owned(b.to_string()),
}
}
}
impl<T, R> Info<T, R> {
pub fn map_token<F, U>(self, f: F) -> Info<U, R>
where
F: FnOnce(T) -> U,
{
use self::Info::*;
match self {
Token(t) => Token(f(t)),
Range(r) => Range(r),
Owned(s) => Owned(s),
Static(x) => Static(x),
}
}
pub fn map_range<F, S>(self, f: F) -> Info<T, S>
where
F: FnOnce(R) -> S,
{
use self::Info::*;
match self {
Token(t) => Token(t),
Range(r) => Range(f(r)),
Owned(s) => Owned(s),
Static(x) => Static(x),
}
}
}
impl<T: PartialEq, R: PartialEq> PartialEq for Info<T, R> {
fn eq(&self, other: &Info<T, R>) -> bool {
match (self, other) {
(&Info::Token(ref l), &Info::Token(ref r)) => l == r,
(&Info::Range(ref l), &Info::Range(ref r)) => l == r,
(&Info::Owned(ref l), &Info::Owned(ref r)) => l == r,
(&Info::Static(l), &Info::Owned(ref r)) => l == r,
(&Info::Owned(ref l), &Info::Static(r)) => l == r,
(&Info::Static(l), &Info::Static(r)) => l == r,
_ => false,
}
}
}
impl<T: fmt::Display, R: fmt::Display> fmt::Display for Info<T, R> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Info::Token(ref c) => write!(f, "`{}`", c),
Info::Range(ref c) => write!(f, "`{}`", c),
Info::Owned(ref s) => write!(f, "{}", s),
Info::Static(s) => write!(f, "{}", s),
}
}
}
impl<R> From<char> for Info<char, R> {
fn from(s: char) -> Info<char, R> {
Info::Token(s)
}
}
impl<T, R> From<String> for Info<T, R> {
fn from(s: String) -> Info<T, R> {
Info::Owned(s)
}
}
impl<T, R> From<&'static str> for Info<T, R> {
fn from(s: &'static str) -> Info<T, R> {
Info::Static(s)
}
}
impl<R> From<u8> for Info<u8, R> {
fn from(s: u8) -> Info<u8, R> {
Info::Token(s)
}
}
/// Enum used to store information about an error that has occurred during parsing.
#[derive(Debug)]
pub enum Error<T, R> {
/// Error indicating an unexpected token has been encountered in the stream
Unexpected(Info<T, R>),
/// Error indicating that the parser expected something else
Expected(Info<T, R>),
/// Generic message
Message(Info<T, R>),
/// Variant for containing other types of errors
Other(Box<dyn StdError + Send + Sync>),
}
impl<Item, Range> StreamError<Item, Range> for Error<Item, Range>
where
Item: PartialEq,
Range: PartialEq,
{
#[inline]
fn unexpected_token(token: Item) -> Self {
Error::Unexpected(Info::Token(token))
}
#[inline]
fn unexpected_range(token: Range) -> Self {
Error::Unexpected(Info::Range(token))
}
#[inline]
fn unexpected_format<T>(msg: T) -> Self
where
T: fmt::Display,
{
Error::Unexpected(Info::Owned(msg.to_string()))
}
#[inline]
fn unexpected_static_message(msg: &'static str) -> Self {
Error::Unexpected(Info::Static(msg))
}
#[inline]
fn expected_token(token: Item) -> Self {
Error::Expected(Info::Token(token))
}
#[inline]
fn expected_range(token: Range) -> Self {
Error::Expected(Info::Range(token))
}
#[inline]
fn expected_format<T>(msg: T) -> Self
where
T: fmt::Display,
{
Error::Expected(Info::Owned(msg.to_string()))
}
#[inline]
fn expected_static_message(msg: &'static str) -> Self {
Error::Expected(Info::Static(msg))
}
#[inline]
fn message_format<T>(msg: T) -> Self
where
T: fmt::Display,
{
Error::Message(Info::Owned(msg.to_string()))
}
#[inline]
fn message_static_message(msg: &'static str) -> Self {
Error::Message(Info::Static(msg))
}
#[inline]
fn message_token(token: Item) -> Self {
Error::Message(Info::Token(token))
}
#[inline]
fn message_range(token: Range) -> Self {
Error::Message(Info::Range(token))
}
fn is_unexpected_end_of_input(&self) -> bool {
*self == Self::end_of_input()
}
#[inline]
fn other<E>(err: E) -> Self
where
E: StdError + Send + Sync + 'static,
{
err.into()
}
#[inline]
fn into_other<T>(self) -> T
where
T: StreamError<Item, Range>,
{
match self {
Error::Unexpected(info) => match info {
Info::Token(x) => T::unexpected_token(x),
Info::Range(x) => T::unexpected_range(x),
Info::Static(x) => T::unexpected_static_message(x),
Info::Owned(x) => T::unexpected_format(x),
},
Error::Expected(info) => match info {
Info::Token(x) => T::expected_token(x),
Info::Range(x) => T::expected_range(x),
Info::Static(x) => T::expected_static_message(x),
Info::Owned(x) => T::expected_format(x),
},
Error::Message(info) => match info {
Info::Token(x) => T::expected_token(x),
Info::Range(x) => T::expected_range(x),
Info::Static(x) => T::expected_static_message(x),
Info::Owned(x) => T::expected_format(x),
},
Error::Other(err) => T::message_format(err),
}
}
}
impl<Item, Range, Position> crate::error::ParseError<Item, Range, Position> for Error<Item, Range>
where
Item: PartialEq,
Range: PartialEq,
Position: Default,
{
type StreamError = Self;
#[inline]
fn empty(_: Position) -> Self {
Self::message_static_message("")
}
#[inline]
fn from_error(_: Position, err: Self::StreamError) -> Self {
err
}
#[inline]
fn position(&self) -> Position {
Position::default()
}
#[inline]
fn set_position(&mut self, _position: Position) {}
#[inline]
fn add(&mut self, err: Self::StreamError) {
*self = err;
}
#[inline]
fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
where
F: FnOnce(&mut Tracked<Self>),
{
f(self_);
self_.error = info;
}
fn is_unexpected_end_of_input(&self) -> bool {
*self == Self::end_of_input()
}
#[inline]
fn into_other<T>(self) -> T
where
T: crate::error::ParseError<Item, Range, Position>,
{
T::from_error(Position::default(), StreamError::into_other(self))
}
}
impl<Item, Range, Position> crate::error::ParseErrorInto<Item, Range, Position>
for Errors<Item, Range, Position>
{
fn into_other_error<T, Item2, Range2, Position2>(self) -> T
where
T: crate::error::ParseError<Item2, Range2, Position2>,
Item2: From<Item>,
Range2: From<Range>,
Position2: From<Position>,
{
let mut error = T::empty(self.position.into());
for err in self.errors {
error.add(crate::error::StreamErrorInto::<Item, Range>::into_other_error(err));
}
error
}
}
impl<Item, Range> crate::error::StreamErrorInto<Item, Range> for Error<Item, Range> {
fn into_other_error<T, Item2, Range2>(self) -> T
where
T: crate::error::StreamError<Item2, Range2>,
Item2: From<Item>,
Range2: From<Range>,
{
match self {
Error::Unexpected(info) => match info {
Info::Token(x) => T::unexpected_token(x.into()),
Info::Range(x) => T::unexpected_range(x.into()),
Info::Static(x) => T::unexpected_static_message(x),
Info::Owned(x) => T::unexpected_format(x),
},
Error::Expected(info) => match info {
Info::Token(x) => T::expected_token(x.into()),
Info::Range(x) => T::expected_range(x.into()),
Info::Static(x) => T::expected_static_message(x),
Info::Owned(x) => T::expected_format(x),
},
Error::Message(info) => match info {
Info::Token(x) => T::expected_token(x.into()),
Info::Range(x) => T::expected_range(x.into()),
Info::Static(x) => T::expected_static_message(x),
Info::Owned(x) => T::expected_format(x),
},
Error::Other(err) => T::message_format(err),
}
}
}
impl<Item, Range, Position> crate::error::ParseError<Item, Range, Position>
for Errors<Item, Range, Position>
where
Item: PartialEq,
Range: PartialEq,
Position: Ord + Clone,
{
type StreamError = Error<Item, Range>;
#[inline]
fn empty(pos: Position) -> Self {
Errors::empty(pos)
}
#[inline]
fn from_error(position: Position, err: Self::StreamError) -> Self {
Self::new(position, err)
}
#[inline]
fn position(&self) -> Position {
self.position.clone()
}
#[inline]
fn set_position(&mut self, position: Position) {
self.position = position;
}
#[inline]
fn merge(self, other: Self) -> Self {
Errors::merge(self, other)
}
#[inline]
fn add(&mut self, err: Self::StreamError) {
self.add_error(err);
}
#[inline]
fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
where
F: FnOnce(&mut Tracked<Self>),
{
let start = self_.error.errors.len();
f(self_);
// Replace all expected errors that were added from the previous add_error
// with this expected error
let mut i = 0;
self_.error.errors.retain(|e| {
if i < start {
i += 1;
true
} else {
match *e {
Error::Expected(_) => false,
_ => true,
}
}
});
self_.error.add(info);
}
fn clear_expected(&mut self) {
self.errors.retain(|e| match *e {
Error::Expected(_) => false,
_ => true,
})
}
fn is_unexpected_end_of_input(&self) -> bool {
self.errors
.iter()
.any(StreamError::is_unexpected_end_of_input)
}
#[inline]
fn into_other<T>(mut self) -> T
where
T: crate::error::ParseError<Item, Range, Position>,
{
match self.errors.pop() {
Some(err) => T::from_error(self.position, StreamError::into_other(err)),
None => T::empty(self.position),
}
}
}
impl<T, R> Error<T, R> {
pub fn map_token<F, U>(self, f: F) -> Error<U, R>
where
F: FnOnce(T) -> U,
{
use self::Error::*;
match self {
Unexpected(x) => Unexpected(x.map_token(f)),
Expected(x) => Expected(x.map_token(f)),
Message(x) => Message(x.map_token(f)),
Other(x) => Other(x),
}
}
pub fn map_range<F, S>(self, f: F) -> Error<T, S>
where
F: FnOnce(R) -> S,
{
use self::Error::*;
match self {
Unexpected(x) => Unexpected(x.map_range(f)),
Expected(x) => Expected(x.map_range(f)),
Message(x) => Message(x.map_range(f)),
Other(x) => Other(x),
}
}
}
impl<T: PartialEq, R: PartialEq> PartialEq for Error<T, R> {
fn eq(&self, other: &Error<T, R>) -> bool {
match (self, other) {
(&Error::Unexpected(ref l), &Error::Unexpected(ref r))
| (&Error::Expected(ref l), &Error::Expected(ref r))
| (&Error::Message(ref l), &Error::Message(ref r)) => l == r,
_ => false,
}
}
}
impl<T, R, E> From<E> for Error<T, R>
where
E: StdError + 'static + Send + Sync,
{
fn from(e: E) -> Error<T, R> {
Error::Other(Box::new(e))
}
}
impl<T, R> Error<T, R> {
/// Returns the `end_of_input` error.
pub fn end_of_input() -> Error<T, R> {
Error::Unexpected("end of input".into())
}
/// Formats a slice of errors in a human readable way.
///
/// ```rust
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::*;
/// # use combine::stream::position::{self, SourcePosition};
///
/// # fn main() {
/// let input = r"
/// ,123
/// ";
/// let result = spaces().silent().with(char('.').or(char('a')).or(digit()))
/// .easy_parse(position::Stream::new(input));
/// let m = format!("{}", result.unwrap_err());
/// let expected = r"Parse error at line: 2, column: 3
/// Unexpected `,`
/// Expected `.`, `a` or digit
/// ";
/// assert_eq!(m, expected);
/// # }
/// ```
pub fn fmt_errors(errors: &[Error<T, R>], f: &mut fmt::Formatter<'_>) -> fmt::Result
where
T: fmt::Display,
R: fmt::Display,
{
// First print the token that we did not expect
// There should really just be one unexpected message at this point though we print them
// all to be safe
let unexpected = errors.iter().filter(|e| match **e {
Error::Unexpected(_) => true,
_ => false,
});
for error in unexpected {
writeln!(f, "{}", error)?;
}
// Then we print out all the things that were expected in a comma separated list
// 'Expected 'a', 'expression' or 'let'
let iter = || {
errors.iter().filter_map(|e| match *e {
Error::Expected(ref err) => Some(err),
_ => None,
})
};
let expected_count = iter().count();
for (i, message) in iter().enumerate() {
let s = match i {
0 => "Expected",
_ if i < expected_count - 1 => ",",
// Last expected message to be written
_ => " or",
};
write!(f, "{} {}", s, message)?;
}
if expected_count != 0 {
writeln!(f)?;
}
// If there are any generic messages we print them out last
let messages = errors.iter().filter(|e| match **e {
Error::Message(_) | Error::Other(_) => true,
_ => false,
});
for error in messages {
writeln!(f, "{}", error)?;
}
Ok(())
}
}
/// Convenience alias over `Errors` for `StreamOnce` types which makes it possible to specify the
/// `Errors` type from a `StreamOnce` by writing `ParseError<Input>` instead of `Errors<Input::Token,
/// Input::Range, Input::Position>`
pub type ParseError<S> =
Errors<<S as StreamOnce>::Token, <S as StreamOnce>::Range, <S as StreamOnce>::Position>;
/// Struct which hold information about an error that occurred at a specific position.
/// Can hold multiple instances of `Error` if more that one error occurred in the same position.
#[derive(Debug, PartialEq)]
pub struct Errors<T, R, P> {
/// The position where the error occurred
pub position: P,
/// A vector containing specific information on what errors occurred at `position`. Usually
/// a fully formed message contains one `Unexpected` error and one or more `Expected` errors.
/// `Message` and `Other` may also appear (`combine` never generates these errors on its own)
/// and may warrant custom handling.
pub errors: Vec<Error<T, R>>,
}
impl<T, R, P> Errors<T, R, P> {
/// Constructs a new `ParseError` which occurred at `position`.
#[inline]
pub fn new(position: P, error: Error<T, R>) -> Errors<T, R, P> {
Self::from_errors(position, vec![error])
}
/// Constructs an error with no other information than the position it occurred at.
#[inline]
pub fn empty(position: P) -> Errors<T, R, P> {
Self::from_errors(position, vec![])
}
/// Constructs a `ParseError` with multiple causes.
#[inline]
pub fn from_errors(position: P, errors: Vec<Error<T, R>>) -> Errors<T, R, P> {
Errors { position, errors }
}
/// Constructs an end of input error. Should be returned by parsers which encounter end of
/// input unexpectedly.
#[inline]
pub fn end_of_input(position: P) -> Errors<T, R, P> {
Self::new(position, Error::end_of_input())
}
/// Adds an error if `error` does not exist in this `ParseError` already (as determined byte
/// `PartialEq`).
pub fn add_error(&mut self, error: Error<T, R>)
where
T: PartialEq,
R: PartialEq,
{
// Don't add duplicate errors
if self.errors.iter().all(|err| *err != error) {
self.errors.push(error);
}
}
/// Removes all `Expected` errors in `self` and adds `info` instead.
pub fn set_expected(&mut self, info: Info<T, R>) {
// Remove all other expected messages
self.errors.retain(|e| match *e {
Error::Expected(_) => false,
_ => true,
});
self.errors.push(Error::Expected(info));
}
/// Merges two `ParseError`s. If they exist at the same position the errors of `other` are
/// added to `self` (using `add_error` to skip duplicates). If they are not at the same
/// position the error furthest ahead are returned, ignoring the other `ParseError`.
pub fn merge(mut self, mut other: Errors<T, R, P>) -> Errors<T, R, P>
where
P: Ord,
T: PartialEq,
R: PartialEq,
{
use std::cmp::Ordering;
// Only keep the errors which occurred after consuming the most amount of data
match self.position.cmp(&other.position) {
Ordering::Less => other,
Ordering::Greater => self,
Ordering::Equal => {
for message in other.errors.drain(..) {
self.add_error(message);
}
self
}
}
}
/// Maps the position to a new value
pub fn map_position<F, Q>(self, f: F) -> Errors<T, R, Q>
where
F: FnOnce(P) -> Q,
{
Errors::from_errors(f(self.position), self.errors)
}
/// Maps all token variants to a new value
pub fn map_token<F, U>(self, mut f: F) -> Errors<U, R, P>
where
F: FnMut(T) -> U,
{
Errors::from_errors(
self.position,
self.errors
.into_iter()
.map(|error| error.map_token(&mut f))
.collect(),
)
}
/// Maps all range variants to a new value.
///
/// ```
/// use combine::*;
/// use combine::parser::range::range;
/// println!(
/// "{}",
/// range(&"HTTP"[..])
/// .easy_parse("HTT")
/// .unwrap_err()
/// .map_range(|bytes| format!("{:?}", bytes))
/// );
/// ```
pub fn map_range<F, S>(self, mut f: F) -> Errors<T, S, P>
where
F: FnMut(R) -> S,
{
Errors::from_errors(
self.position,
self.errors
.into_iter()
.map(|error| error.map_range(&mut f))
.collect(),
)
}
}
impl<T, R, P> StdError for Errors<T, R, P>
where
P: fmt::Display + fmt::Debug,
T: fmt::Display + fmt::Debug,
R: fmt::Display + fmt::Debug,
{
fn description(&self) -> &str {
"parse error"
}
}
impl<T, R, P> fmt::Display for Errors<T, R, P>
where
P: fmt::Display,
T: fmt::Display,
R: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Parse error at {}", self.position)?;
Error::fmt_errors(&self.errors, f)
}
}
impl<T: fmt::Display, R: fmt::Display> fmt::Display for Error<T, R> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Error::Unexpected(ref c) => write!(f, "Unexpected {}", c),
Error::Expected(ref s) => write!(f, "Expected {}", s),
Error::Message(ref msg) => msg.fmt(f),
Error::Other(ref err) => err.fmt(f),
}
}
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct Stream<S>(pub S);
impl<S> From<S> for Stream<S> {
fn from(stream: S) -> Self {
Stream(stream)
}
}
impl<S> ResetStream for Stream<S>
where
S: ResetStream + Positioned,
S::Token: PartialEq,
S::Range: PartialEq,
{
type Checkpoint = S::Checkpoint;
fn checkpoint(&self) -> Self::Checkpoint {
self.0.checkpoint()
}
fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
self.0
.reset(checkpoint)
.map_err(crate::error::ParseError::into_other)
}
}
impl<S> StreamOnce for Stream<S>
where
S: StreamOnce + Positioned,
S::Token: PartialEq,
S::Range: PartialEq,
{
type Token = S::Token;
type Range = S::Range;
type Position = S::Position;
type Error = ParseError<S>;
#[inline]
fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>> {
self.0.uncons().map_err(StreamError::into_other)
}
fn is_partial(&self) -> bool {
self.0.is_partial()
}
}
impl<S> RangeStreamOnce for Stream<S>
where
S: RangeStream,
S::Token: PartialEq,
S::Range: PartialEq,
{
#[inline]
fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
self.0.uncons_range(size).map_err(StreamError::into_other)
}
#[inline]
fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
self.0.uncons_while(f).map_err(StreamError::into_other)
}
#[inline]
fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
self.0.uncons_while1(f).map_err(StreamError::into_other)
}
#[inline]
fn distance(&self, end: &Self::Checkpoint) -> usize {
self.0.distance(end)
}
fn range(&self) -> Self::Range {
self.0.range()
}
}
impl<S> Positioned for Stream<S>
where
S: StreamOnce + Positioned,
S::Token: PartialEq,
S::Range: PartialEq,
{
fn position(&self) -> S::Position {
self.0.position()
}
}

1896
vendor/combine/src/stream/mod.rs vendored Normal file

File diff suppressed because it is too large Load Diff

465
vendor/combine/src/stream/position.rs vendored Normal file
View File

@@ -0,0 +1,465 @@
use crate::{
error::{ParseError, ParseResult, StreamError},
lib::fmt,
stream::{
IteratorStream, Positioned, RangeStreamOnce, ResetStream, SliceStream, StreamErrorFor,
StreamOnce,
},
};
#[cfg(feature = "std")]
use crate::stream::read;
/// Trait for tracking the current position of a `Stream`.
pub trait Positioner<Item> {
/// The type which keeps track of the position
type Position: Clone + Ord;
type Checkpoint: Clone;
/// Returns the current position
fn position(&self) -> Self::Position;
/// Updates the position given that `token` has been taken from the stream
fn update(&mut self, token: &Item);
fn checkpoint(&self) -> Self::Checkpoint;
fn reset(&mut self, checkpoint: Self::Checkpoint);
}
/// Trait for tracking the current position of a `RangeStream`.
pub trait RangePositioner<Item, Range>: Positioner<Item> {
/// Updates the position given that `range` has been taken from the stream
fn update_range(&mut self, range: &Range);
}
/// Defines a default `Positioner` type for a particular `Stream` type.
pub trait DefaultPositioned {
type Positioner: Default;
}
impl<'a> DefaultPositioned for &'a str {
type Positioner = SourcePosition;
}
impl<'a, T> DefaultPositioned for &'a [T] {
type Positioner = IndexPositioner;
}
impl<'a, T> DefaultPositioned for SliceStream<'a, T> {
type Positioner = IndexPositioner;
}
impl<T> DefaultPositioned for IteratorStream<T> {
type Positioner = IndexPositioner;
}
#[cfg(feature = "std")]
impl<R> DefaultPositioned for read::Stream<R> {
type Positioner = IndexPositioner;
}
/// The `Stream<Input>` struct maintains the current position in the stream `Input` using
/// the `Positioner` trait to track the position.
///
/// ```
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::stream::easy;
/// # use combine::stream::position;
/// # fn main() {
/// let result = token(b'9')
/// .message("Not a nine")
/// .easy_parse(position::Stream::new(&b"8"[..]));
/// assert_eq!(result, Err(easy::Errors {
/// position: 0,
/// errors: vec![
/// easy::Error::Unexpected(b'8'.into()),
/// easy::Error::Expected(b'9'.into()),
/// easy::Error::Message("Not a nine".into())
/// ]
/// }));
/// # }
/// ```
#[derive(Clone, Debug, PartialEq)]
pub struct Stream<Input, X> {
/// The input stream used when items are requested
pub input: Input,
/// The positioner used to update the current position
pub positioner: X,
}
impl<Input, X> Stream<Input, X>
where
Input: StreamOnce,
X: Positioner<Input::Token>,
{
/// Creates a new `Stream<Input, X>` from an input stream and a positioner.
pub fn with_positioner(input: Input, positioner: X) -> Stream<Input, X> {
Stream { input, positioner }
}
}
impl<Input> Stream<Input, Input::Positioner>
where
Input: StreamOnce + DefaultPositioned,
Input::Positioner: Positioner<Input::Token>,
{
/// Creates a new `Stream<Input, X>` from an input stream and its default positioner.
pub fn new(input: Input) -> Stream<Input, Input::Positioner> {
Stream::with_positioner(input, Input::Positioner::default())
}
}
impl<Input, X, S> Positioned for Stream<Input, X>
where
Input: StreamOnce,
X: Positioner<Input::Token>,
S: StreamError<Input::Token, Input::Range>,
Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
{
#[inline]
fn position(&self) -> Self::Position {
self.positioner.position()
}
}
impl<Input, X, S> StreamOnce for Stream<Input, X>
where
Input: StreamOnce,
X: Positioner<Input::Token>,
S: StreamError<Input::Token, Input::Range>,
Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
{
type Token = Input::Token;
type Range = Input::Range;
type Position = X::Position;
type Error = Input::Error;
#[inline]
fn uncons(&mut self) -> Result<Input::Token, StreamErrorFor<Self>> {
self.input.uncons().map(|c| {
self.positioner.update(&c);
c
})
}
fn is_partial(&self) -> bool {
self.input.is_partial()
}
}
impl<Item, T> Positioner<Item> for &'_ mut T
where
Item: Clone,
T: ?Sized + Positioner<Item>,
{
type Position = T::Position;
type Checkpoint = T::Checkpoint;
#[inline]
fn position(&self) -> T::Position {
(**self).position()
}
#[inline]
fn update(&mut self, item: &Item) {
(**self).update(item)
}
#[inline]
fn checkpoint(&self) -> Self::Checkpoint {
(**self).checkpoint()
}
#[inline]
fn reset(&mut self, checkpoint: Self::Checkpoint) {
(**self).reset(checkpoint)
}
}
impl<Item, Range, T> RangePositioner<Item, Range> for &'_ mut T
where
Item: Clone,
Range: Clone + crate::stream::Range,
T: ?Sized + RangePositioner<Item, Range>,
{
fn update_range(&mut self, range: &Range) {
(**self).update_range(range);
}
}
/// The `IndexPositioner<Item, Range>` struct maintains the current index into the stream `Input`. The
/// initial index is index 0. Each `Item` committed increments the index by 1; each `range` committed
/// increments the position by `range.len()`.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct IndexPositioner(usize);
impl<Item> Positioner<Item> for IndexPositioner
where
Item: Clone,
{
type Position = usize;
type Checkpoint = Self;
#[inline]
fn position(&self) -> usize {
self.0
}
#[inline]
fn update(&mut self, _item: &Item) {
self.0 += 1
}
#[inline]
fn checkpoint(&self) -> Self::Checkpoint {
self.clone()
}
#[inline]
fn reset(&mut self, checkpoint: Self::Checkpoint) {
*self = checkpoint;
}
}
impl IndexPositioner {
pub fn new() -> IndexPositioner {
IndexPositioner::new_with_position(0)
}
pub fn new_with_position(position: usize) -> IndexPositioner {
IndexPositioner(position)
}
}
impl<Item, Range> RangePositioner<Item, Range> for IndexPositioner
where
Item: Clone,
Range: Clone + crate::stream::Range,
{
fn update_range(&mut self, range: &Range) {
self.0 += range.len()
}
}
/// Struct which represents a position in a source file.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct SourcePosition {
/// Current line of the input
pub line: i32,
/// Current column of the input
pub column: i32,
}
impl Default for SourcePosition {
fn default() -> Self {
SourcePosition { line: 1, column: 1 }
}
}
impl fmt::Display for SourcePosition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "line: {}, column: {}", self.line, self.column)
}
}
impl SourcePosition {
pub fn new() -> Self {
SourcePosition::default()
}
}
impl Positioner<char> for SourcePosition {
type Position = SourcePosition;
type Checkpoint = Self;
#[inline]
fn position(&self) -> SourcePosition {
*self
}
#[inline]
fn update(&mut self, token: &char) {
self.column += 1;
if *token == '\n' {
self.column = 1;
self.line += 1;
}
}
#[inline]
fn checkpoint(&self) -> Self::Checkpoint {
*self
}
#[inline]
fn reset(&mut self, checkpoint: Self::Checkpoint) {
*self = checkpoint;
}
}
impl Positioner<u8> for SourcePosition {
type Position = SourcePosition;
type Checkpoint = Self;
#[inline]
fn position(&self) -> SourcePosition {
*self
}
#[inline]
fn update(&mut self, token: &u8) {
self.column += 1;
if *token == b'\n' {
self.column = 1;
self.line += 1;
}
}
#[inline]
fn checkpoint(&self) -> Self::Checkpoint {
*self
}
#[inline]
fn reset(&mut self, checkpoint: Self::Checkpoint) {
*self = checkpoint;
}
}
impl<'a> RangePositioner<char, &'a str> for SourcePosition {
fn update_range(&mut self, range: &&'a str) {
for c in range.chars() {
self.update(&c);
}
}
}
impl<Input, X, S> RangeStreamOnce for Stream<Input, X>
where
Input: RangeStreamOnce,
X: RangePositioner<Input::Token, Input::Range>,
S: StreamError<Input::Token, Input::Range>,
Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
Input::Position: Clone + Ord,
{
#[inline]
fn uncons_range(&mut self, size: usize) -> Result<Input::Range, StreamErrorFor<Self>> {
self.input.uncons_range(size).map(|range| {
self.positioner.update_range(&range);
range
})
}
#[inline]
fn uncons_while<F>(&mut self, mut predicate: F) -> Result<Input::Range, StreamErrorFor<Self>>
where
F: FnMut(Input::Token) -> bool,
{
let positioner = &mut self.positioner;
self.input.uncons_while(|t| {
if predicate(t.clone()) {
positioner.update(&t);
true
} else {
false
}
})
}
#[inline]
fn uncons_while1<F>(
&mut self,
mut predicate: F,
) -> ParseResult<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
let positioner = &mut self.positioner;
self.input.uncons_while1(|t| {
if predicate(t.clone()) {
positioner.update(&t);
true
} else {
false
}
})
}
#[inline]
fn distance(&self, end: &Self::Checkpoint) -> usize {
self.input.distance(&end.input)
}
fn range(&self) -> Self::Range {
self.input.range()
}
}
impl<Input, X, S> ResetStream for Stream<Input, X>
where
Input: ResetStream,
X: Positioner<Input::Token>,
S: StreamError<Input::Token, Input::Range>,
Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
{
type Checkpoint = Stream<Input::Checkpoint, X::Checkpoint>;
fn checkpoint(&self) -> Self::Checkpoint {
Stream {
input: self.input.checkpoint(),
positioner: self.positioner.checkpoint(),
}
}
fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
self.input.reset(checkpoint.input)?;
self.positioner.reset(checkpoint.positioner);
Ok(())
}
}
#[cfg(all(feature = "std", test))]
mod tests {
use crate::Parser;
use super::*;
#[test]
fn test_positioner() {
let input = ["a".to_string(), "b".to_string()];
let mut parser = crate::any();
let result = parser.parse(Stream::new(&input[..]));
assert_eq!(
result,
Ok((
"a".to_string(),
Stream::with_positioner(
&["b".to_string()][..],
IndexPositioner::new_with_position(1)
)
))
);
}
#[test]
fn test_range_positioner() {
let input = ["a".to_string(), "b".to_string(), "c".to_string()];
let mut parser = crate::parser::range::take(2);
let result = parser.parse(Stream::new(&input[..]));
assert_eq!(
result,
Ok((
&["a".to_string(), "b".to_string()][..],
Stream::with_positioner(
&["c".to_string()][..],
IndexPositioner::new_with_position(2)
)
))
);
}
}

210
vendor/combine/src/stream/read.rs vendored Normal file
View File

@@ -0,0 +1,210 @@
use std::{
fmt,
io::{self, Bytes, Read},
};
use crate::{
error::{ParseError, StreamError, Tracked},
stream::{StreamErrorFor, StreamOnce},
};
#[derive(Debug)]
pub enum Error {
Unexpected,
EndOfInput,
Io(io::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Unexpected => write!(f, "unexpected parse"),
Error::EndOfInput => write!(f, "unexpected end of input"),
Error::Io(err) => write!(f, "{}", err),
}
}
}
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Error::Unexpected, Error::Unexpected) => true,
(Error::EndOfInput, Error::EndOfInput) => true,
_ => false,
}
}
}
impl<Item, Range> StreamError<Item, Range> for Error {
#[inline]
fn unexpected_token(_: Item) -> Self {
Error::Unexpected
}
#[inline]
fn unexpected_range(_: Range) -> Self {
Error::Unexpected
}
#[inline]
fn unexpected_format<T>(_: T) -> Self
where
T: fmt::Display,
{
Error::Unexpected
}
#[inline]
fn expected_token(_: Item) -> Self {
Error::Unexpected
}
#[inline]
fn expected_range(_: Range) -> Self {
Error::Unexpected
}
#[inline]
fn expected_format<T>(_: T) -> Self
where
T: fmt::Display,
{
Error::Unexpected
}
#[inline]
fn message_format<T>(_: T) -> Self
where
T: fmt::Display,
{
Error::Unexpected
}
#[inline]
fn message_token(_: Item) -> Self {
Error::Unexpected
}
#[inline]
fn message_range(_: Range) -> Self {
Error::Unexpected
}
#[inline]
fn end_of_input() -> Self {
Error::EndOfInput
}
#[inline]
fn is_unexpected_end_of_input(&self) -> bool {
*self == Error::EndOfInput
}
#[inline]
fn into_other<T>(self) -> T
where
T: StreamError<Item, Range>,
{
match self {
Error::Unexpected => T::unexpected_static_message("parse"),
Error::EndOfInput => T::end_of_input(),
Error::Io(err) => T::other(err),
}
}
}
impl<Item, Range, Position> ParseError<Item, Range, Position> for Error
where
Position: Default,
{
type StreamError = Self;
#[inline]
fn empty(_position: Position) -> Self {
Error::Unexpected
}
#[inline]
fn from_error(_: Position, err: Self::StreamError) -> Self {
err
}
#[inline]
fn set_position(&mut self, _position: Position) {}
#[inline]
fn add(&mut self, err: Self::StreamError) {
*self = match (&*self, err) {
(Error::EndOfInput, _) => Error::EndOfInput,
(_, err) => err,
};
}
#[inline]
fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
where
F: FnOnce(&mut Tracked<Self>),
{
f(self_);
self_.error = info;
}
fn is_unexpected_end_of_input(&self) -> bool {
*self == Error::EndOfInput
}
#[inline]
fn into_other<T>(self) -> T
where
T: ParseError<Item, Range, Position>,
{
T::from_error(Position::default(), StreamError::into_other(self))
}
}
pub struct Stream<R> {
bytes: Bytes<R>,
}
impl<R: Read> StreamOnce for Stream<R> {
type Token = u8;
type Range = &'static [u8];
type Position = usize;
type Error = Error;
#[inline]
fn uncons(&mut self) -> Result<u8, StreamErrorFor<Self>> {
match self.bytes.next() {
Some(Ok(b)) => Ok(b),
Some(Err(err)) => Err(Error::Io(err)),
None => Err(Error::EndOfInput),
}
}
}
impl<R> Stream<R>
where
R: Read,
{
/// Creates a `StreamOnce` instance from a value implementing `std::io::Read`.
///
/// NOTE: This type do not implement `Positioned` and `Clone` and must be wrapped with types
/// such as `BufferedStreamRef` and `State` to become a `Stream` which can be parsed
///
/// ```rust
/// # #![cfg(feature = "std")]
/// # extern crate combine;
/// use combine::*;
/// use combine::parser::byte::*;
/// use combine::stream::read;
/// use combine::stream::buffered;
/// use combine::stream::position;
/// use std::io::Read;
///
/// # fn main() {
/// let input: &[u8] = b"123,";
/// let stream = buffered::Stream::new(position::Stream::new(read::Stream::new(input)), 1);
/// let result = (many(digit()), byte(b','))
/// .parse(stream)
/// .map(|t| t.0);
/// assert_eq!(result, Ok((vec![b'1', b'2', b'3'], b',')));
/// # }
/// ```
pub fn new(read: R) -> Stream<R> {
Stream {
bytes: read.bytes(),
}
}
}

157
vendor/combine/src/stream/span.rs vendored Normal file
View File

@@ -0,0 +1,157 @@
use crate::lib::marker::PhantomData;
use crate::{
error::{ParseErrorInto, ParseResult, StreamErrorInto},
stream::{ResetStream, StreamErrorFor},
Positioned, RangeStream, RangeStreamOnce, StreamOnce,
};
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Span<P> {
pub start: P,
pub end: P,
}
impl<P> From<P> for Span<P>
where
P: Clone,
{
#[inline]
fn from(p: P) -> Self {
Self {
start: p.clone(),
end: p,
}
}
}
impl<P> Span<P> {
pub fn map<Q>(self, mut f: impl FnMut(P) -> Q) -> Span<Q> {
Span {
start: f(self.start),
end: f(self.end),
}
}
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct Stream<S, E>(pub S, PhantomData<fn(E) -> E>);
impl<S, E> From<S> for Stream<S, E> {
fn from(stream: S) -> Self {
Stream(stream, PhantomData)
}
}
impl<S, E> ResetStream for Stream<S, E>
where
S: ResetStream + Positioned,
S::Token: PartialEq,
S::Range: PartialEq,
E: crate::error::ParseError<S::Token, S::Range, Span<S::Position>>,
S::Error: ParseErrorInto<S::Token, S::Range, S::Position>,
<S::Error as crate::error::ParseError<S::Token, S::Range, S::Position>>::StreamError:
StreamErrorInto<S::Token, S::Range>,
{
type Checkpoint = S::Checkpoint;
#[inline]
fn checkpoint(&self) -> Self::Checkpoint {
self.0.checkpoint()
}
#[inline]
fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
self.0
.reset(checkpoint)
.map_err(ParseErrorInto::into_other_error)
}
}
impl<S, E> StreamOnce for Stream<S, E>
where
S: StreamOnce + Positioned,
S::Token: PartialEq,
S::Range: PartialEq,
E: crate::error::ParseError<S::Token, S::Range, Span<S::Position>>,
S::Error: ParseErrorInto<S::Token, S::Range, S::Position>,
<S::Error as crate::error::ParseError<S::Token, S::Range, S::Position>>::StreamError:
StreamErrorInto<S::Token, S::Range>,
{
type Token = S::Token;
type Range = S::Range;
type Position = Span<S::Position>;
type Error = E;
#[inline]
fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>> {
self.0.uncons().map_err(StreamErrorInto::into_other_error)
}
#[inline]
fn is_partial(&self) -> bool {
self.0.is_partial()
}
}
impl<S, E> RangeStreamOnce for Stream<S, E>
where
S: RangeStream,
S::Token: PartialEq,
S::Range: PartialEq,
E: crate::error::ParseError<S::Token, S::Range, Span<S::Position>>,
S::Error: ParseErrorInto<S::Token, S::Range, S::Position>,
<S::Error as crate::error::ParseError<S::Token, S::Range, S::Position>>::StreamError:
StreamErrorInto<S::Token, S::Range>,
{
#[inline]
fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
self.0
.uncons_range(size)
.map_err(StreamErrorInto::into_other_error)
}
#[inline]
fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
self.0
.uncons_while(f)
.map_err(StreamErrorInto::into_other_error)
}
#[inline]
fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
self.0
.uncons_while1(f)
.map_err(StreamErrorInto::into_other_error)
}
#[inline]
fn distance(&self, end: &Self::Checkpoint) -> usize {
self.0.distance(end)
}
fn range(&self) -> Self::Range {
self.0.range()
}
}
impl<S, E> Positioned for Stream<S, E>
where
S: StreamOnce + Positioned,
S::Token: PartialEq,
S::Range: PartialEq,
E: crate::error::ParseError<S::Token, S::Range, Span<S::Position>>,
S::Error: ParseErrorInto<S::Token, S::Range, S::Position>,
<S::Error as crate::error::ParseError<S::Token, S::Range, S::Position>>::StreamError:
StreamErrorInto<S::Token, S::Range>,
{
fn position(&self) -> Span<S::Position> {
Span::from(self.0.position())
}
}

91
vendor/combine/src/stream/state.rs vendored Normal file
View File

@@ -0,0 +1,91 @@
use crate::{
error::ParseResult,
stream::{Positioned, RangeStreamOnce, ResetStream, StreamErrorFor, StreamOnce},
};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct Stream<S, U> {
pub stream: S,
pub state: U,
}
impl<S, U> Positioned for Stream<S, U>
where
S: Positioned,
{
#[inline]
fn position(&self) -> Self::Position {
self.stream.position()
}
}
impl<S, U> ResetStream for Stream<S, U>
where
S: ResetStream,
{
type Checkpoint = S::Checkpoint;
#[inline]
fn checkpoint(&self) -> Self::Checkpoint {
self.stream.checkpoint()
}
#[inline]
fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
self.stream.reset(checkpoint)
}
}
impl<S, U> StreamOnce for Stream<S, U>
where
S: StreamOnce,
{
type Token = S::Token;
type Range = S::Range;
type Position = S::Position;
type Error = S::Error;
#[inline]
fn uncons(&mut self) -> Result<S::Token, StreamErrorFor<Self>> {
self.stream.uncons()
}
fn is_partial(&self) -> bool {
self.stream.is_partial()
}
}
impl<S, U> RangeStreamOnce for Stream<S, U>
where
S: RangeStreamOnce,
{
#[inline]
fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
self.stream.uncons_range(size)
}
#[inline]
fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
self.stream.uncons_while(f)
}
fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
where
F: FnMut(Self::Token) -> bool,
{
self.stream.uncons_while1(f)
}
#[inline]
fn distance(&self, end: &Self::Checkpoint) -> usize {
self.stream.distance(end)
}
#[inline]
fn range(&self) -> Self::Range {
self.stream.range()
}
}