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

852
vendor/combine/tests/async.rs vendored Normal file
View File

@@ -0,0 +1,852 @@
#![allow(renamed_and_removed_lints)]
use std::{
cell::Cell,
io::{self, Cursor},
rc::Rc,
str,
};
use {
bytes::{Buf, BytesMut},
combine::{
any, count_min_max,
error::{ParseError, StreamError},
many1, parser,
parser::{
byte::{num, take_until_bytes},
char::{char, digit, letter, string},
choice::optional,
combinator::{
any_partial_state, any_send_partial_state, attempt, from_str, no_partial,
recognize, AnyPartialState, AnySendPartialState,
},
range::{
self, range, recognize_with_value, take, take_fn, take_until_range, take_while,
take_while1,
},
repeat,
},
satisfy, sep_end_by, skip_many, skip_many1,
stream::{easy, RangeStream, StreamErrorFor},
token, Parser,
},
futures::prelude::*,
futures_03_dep as futures,
partial_io::PartialRead,
quick_error::quick_error,
quickcheck::quickcheck,
tokio_dep as tokio,
tokio_util::codec::{Decoder, FramedRead},
};
// Workaround partial_io not working with tokio-0.2
mod support;
use support::*;
quick_error! {
#[derive(Debug)]
enum Error {
Io(err: io::Error) {
display("{}", err)
from()
}
Parse(err: easy::Errors<char, String, usize>) {
display("{}", err)
from()
}
Utf8(err: std::str::Utf8Error) {
display("{}", err)
from()
}
Message(err: String) {
display("{}", err)
from()
}
}
}
macro_rules! mk_parser {
($parser:expr, $self_:expr,()) => {
$parser
};
($parser:expr, $self_:expr,($custom_state:ty)) => {
$parser($self_.1.clone())
};
}
macro_rules! impl_decoder {
($typ: ident, $token: ty, $parser: expr, $custom_state: ty) => {
#[derive(Default)]
struct $typ(AnyPartialState, $custom_state);
impl_decoder!{$typ, $token, $parser; ($custom_state)}
};
($typ: ident, $token: ty, $parser: expr) => {
#[derive(Default)]
struct $typ(AnyPartialState);
impl_decoder!{$typ, $token, $parser; ()}
};
($typ: ident, $token: ty, $parser: expr; ( $($custom_state: tt)* )) => {
impl Decoder for $typ {
type Item = $token;
type Error = Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
(&mut &mut *self).decode(src)
}
fn decode_eof(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
(&mut &mut *self).decode_eof(src)
}
}
impl<'a> Decoder for &'a mut $typ {
type Item = $token;
type Error = Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
self.decode_stream(src, false)
}
fn decode_eof(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
self.decode_stream(src, true)
}
}
impl<'a> $typ {
fn decode_stream(&mut self, src: &mut BytesMut, eof: bool) -> Result<Option<$token>, Error> {
let (opt, removed_len) = {
let str_src = str::from_utf8(&src[..])?;
println!("Decoding `{}`", str_src);
combine::stream::decode_tokio(
any_partial_state(mk_parser!($parser, self, ($($custom_state)*))),
&mut easy::Stream(combine::stream::MaybePartialStream(str_src, !eof)),
&mut self.0,
).map_err(|err| {
// Since err contains references into `src` we must remove these before
// returning the error and before we call `advance` to remove the input we
// just committed
let err = err.map_range(|r| r.to_string())
.map_position(|p| p.translate_position(&str_src[..]));
format!("{}\nIn input: `{}`", err, str_src)
})?
};
src.advance(removed_len);
match opt {
None => println!("Need more input!"),
Some(_) => (),
}
Ok(opt)
}
}
}
}
macro_rules! impl_byte_decoder {
($typ: ident, $token: ty, $parser: expr, $custom_state: ty) => {
#[derive(Default)]
struct $typ(AnyPartialState, $custom_state);
impl_byte_decoder!{$typ, $token, $parser; ($custom_state)}
};
($typ: ident, $token: ty, $parser: expr) => {
#[derive(Default)]
struct $typ(AnyPartialState);
impl_byte_decoder!{$typ, $token, $parser; ()}
};
($typ: ident, $token: ty, $parser: expr; ( $($custom_state: tt)* )) => {
impl Decoder for $typ {
type Item = $token;
type Error = Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
(&mut &mut *self).decode(src)
}
}
impl<'a> Decoder for &'a mut $typ {
type Item = $token;
type Error = Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
let (opt, removed_len) = {
let str_src = &src[..];
println!("Decoding `{:?}`", str_src);
combine::stream::decode(
any_partial_state(mk_parser!($parser, self, ($($custom_state)*))),
&mut easy::Stream(combine::stream::PartialStream(str_src)),
&mut self.0,
).map_err(|err| {
// Since err contains references into `src` we must remove these before
// returning the error and before we call `advance` to remove the input we
// just committed
let err = err.map_range(|r| format!("{:?}", r))
.map_position(|p| p.translate_position(&str_src[..]));
format!("{}\nIn input: `{:?}`", err, str_src)
})?
};
src.advance(removed_len);
match opt {
None => println!("Need more input!"),
Some(_) => (),
}
Ok(opt)
}
}
}
}
use partial_io::{GenNoErrors, GenWouldBlock, PartialOp, PartialWithErrors};
fn run_decoder<B, D, S>(input: &B, seq: S, decoder: D) -> Result<Vec<D::Item>, D::Error>
where
D: Decoder<Error = Error>,
D::Item: ::std::fmt::Debug,
S: IntoIterator<Item = PartialOp> + 'static,
S::IntoIter: Send,
B: ?Sized + AsRef<[u8]>,
{
let ref mut reader = Cursor::new(input.as_ref());
let partial_reader = PartialAsyncRead::new(reader, seq);
tokio_02_dep::runtime::Builder::new()
.basic_scheduler()
.build()
.unwrap()
.block_on(
FramedRead::new(partial_reader, decoder)
.map_ok(|x| {
println!("Decoded `{:?}`", x);
x
})
.try_collect(),
)
}
parser! {
type PartialState = AnyPartialState;
fn basic_parser['a, Input]()(Input) -> String
where [ Input: RangeStream<Token = char, Range = &'a str> ]
{
any_partial_state(
many1(digit()).skip(range(&"\r\n"[..])),
)
}
}
impl_decoder! { Basic, String, basic_parser() }
#[test]
fn many1_skip_no_errors() {
let input = "123\r\n\
456\r\n";
let result = run_decoder(input, vec![], Basic::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), vec!["123".to_string(), "456".to_string()]);
}
parser! {
type PartialState = AnyPartialState;
fn prefix_many_then_parser['a, Input]()(Input) -> String
where [ Input: RangeStream<Token = char, Range = &'a str> ]
{
let integer = from_str(many1::<String, _, _>(digit()));
any_partial_state((char('#'), skip_many(char(' ')), integer)
.then_partial(|t| {
let c = t.2;
count_min_max(c, c, any())
})
)
}
}
parser! {
type PartialState = AnyPartialState;
fn choice_parser['a, Input]()(Input) -> String
where [ Input: RangeStream<Token = char, Range = &'a str> ]
{
any_partial_state(
many1(digit())
.or(many1(letter()))
.skip(range(&"\r\n"[..]))
)
}
}
fn content_length<'a, Input>(
) -> impl Parser<Input, Output = String, PartialState = AnySendPartialState> + 'a
where
Input: RangeStream<Token = char, Range = &'a str> + 'a,
{
let content_length = range("Content-Length: ").with(
range::recognize(skip_many1(digit())).and_then(|digits: &str| {
// Convert the error from `.parse` into an error combine understands
digits
.parse::<usize>()
.map_err(StreamErrorFor::<Input>::other)
}),
);
any_send_partial_state(
(
skip_many(range("\r\n")),
content_length,
range("\r\n\r\n").map(|_| ()),
)
.then_partial(|&mut (_, message_length, _)| {
take(message_length).map(|bytes: &str| bytes.to_owned())
}),
)
}
quickcheck! {
fn many1_skip_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
let input = "123\r\n\
456\r\n\
1\r\n\
5\r\n\
666666\r\n";
let result = run_decoder(input, seq, Basic::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
vec!["123".to_string(), "456".to_string(), "1".to_string(), "5".to_string(), "666666".to_string()]
);
}
fn prefix_many_then_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String, prefix_many_then_parser() }
let input = "# 1a\
# 4abcd\
#0\
#3:?a\
#10abcdefghij";
let result = run_decoder(input, seq, TestParser::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["a", "abcd", "", ":?a", "abcdefghij"]
);
}
fn choice_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String, choice_parser() }
let input = "1\r\n\
abcd\r\n\
123\r\n\
abc\r\n\
1232751\r\n";
let result = run_decoder(input, seq, TestParser::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["1", "abcd", "123", "abc", "1232751"]
);
}
fn recognize_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
recognize(
(skip_many1(digit()), optional((char('.'), skip_many(digit()))))
)
.skip(range(&"\r\n"[..]))
}
let input = "1.0\r\n\
123.123\r\n\
17824\r\n\
3.14\r\n\
1.\r\n\
2\r\n";
let result = run_decoder(input, seq, TestParser::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["1.0", "123.123", "17824", "3.14", "1.", "2"]
);
}
fn recognize_range_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
recognize_with_value(
(skip_many1(digit()), optional((char('.'), skip_many(digit()))))
)
.map(|(r, _)| String::from(r))
.skip(range(&"\r\n"[..]))
}
let input = "1.0\r\n\
123.123\r\n\
17824\r\n\
3.14\r\n\
1.\r\n\
2\r\n";
let result = run_decoder(input, seq, TestParser::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["1.0", "123.123", "17824", "3.14", "1.", "2"]
);
}
fn take_while_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
|counter: Rc<Cell<i32>>|
take_while(move |c| { counter.set(counter.get() + 1); c != '\r' })
.map(String::from)
.skip(range("\r\n")),
Rc<Cell<i32>>
}
let input = "1.0\r\n\
123.123\r\n\
17824\r\n\
3.14\r\n\
\r\n\
2\r\n";
let counter = Rc::new(Cell::new(0));
let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["1.0", "123.123", "17824", "3.14", "", "2"]
);
assert_eq!(counter.get(), 26);
}
fn take_while1_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
|count: Rc<Cell<i32>>|
take_while1(move |c| { count.set(count.get() + 1); c != '\r' })
.map(String::from)
.skip(range("\r\n")),
Rc<Cell<i32>>
}
let input = "1.0\r\n\
123.123\r\n\
17824\r\n\
3.14\r\n\
1.\r\n\
2\r\n";
let counter = Rc::new(Cell::new(0));
let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["1.0", "123.123", "17824", "3.14", "1.", "2"]
);
assert_eq!(counter.get(), 28);
}
fn take_until(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
|count: Rc<Cell<i32>>|
repeat::take_until(token(',').map(move |_| count.set(count.get() + 1))).skip(token(',')),
Rc<Cell<i32>>
}
let input = "123,456,789,";
let counter = Rc::new(Cell::new(0));
let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["123", "456", "789"]
);
assert_eq!(counter.get(), 3);
}
fn take_until_committed(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
|count: Rc<Cell<i32>>| {
let end = attempt((token(':').map(move |_| count.set(count.get() + 1)), token(':')));
repeat::take_until(end).skip((token(':'), token(':')))
},
Rc<Cell<i32>>
}
let input = "123::456::789::";
let counter = Rc::new(Cell::new(0));
let result = run_decoder(input, seq, TestParser(Default::default(), counter.clone()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(
result.unwrap(),
["123", "456", "789"]
);
assert_eq!(counter.get(), 3);
}
fn take_until_range_committed(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, String,
take_until_range("::").map(String::from).skip((token(':'), token(':')))
}
let input = "123::456::789::";
let result = run_decoder(input, seq, TestParser(Default::default()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), ["123", "456", "789"]);
}
fn any_send_partial_state_do_not_forget_state(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, usize,
any_send_partial_state(content_length().map(|bytes| bytes.len()))
}
let input : String = sizes
.iter()
.map(|s| {
format!(
"Content-Length: {}\r\n\r\n{}\r\n",
s,
::std::iter::repeat('a').take(*s).collect::<String>()
)
})
.collect();
let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), sizes);
}
fn take_fn_test(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, usize,
take_fn(|s: &str| s.find("\r\n")).map(|bytes: &str| bytes.parse::<usize>().unwrap()).skip(take(2))
}
let input : String = sizes
.iter()
.map(|s| {
format!(
"{}\r\n",
s,
)
})
.collect();
let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), sizes);
}
fn take_until_bytes_test(sizes: Vec<usize>, seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, usize,
take_until_bytes("\r\n".as_bytes())
.map(|bytes: &str| bytes.parse::<usize>().unwrap())
.skip(take(2))
}
let input : String = sizes
.iter()
.map(|s| {
format!(
"{}\r\n",
s,
)
})
.collect();
let result = run_decoder(input.as_bytes(), seq, TestParser(Default::default()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), sizes);
}
fn num_test(ints: Vec<u16>, seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_byte_decoder!{ TestParser, u16,
num::be_u16()
.skip(take(2))
}
let input: Vec<u8> = ints.iter()
.flat_map(|i| {
let mut v = Vec::new();
v.extend_from_slice(&i.to_be_bytes());
v.extend_from_slice(b"\r\n");
v
})
.collect();
let result = run_decoder(&input, seq, TestParser(Default::default()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), ints);
}
fn sep_end_by_test(seq: PartialWithErrors<GenWouldBlock>) -> () {
impl_decoder!{ TestParser, Vec<String>,
repeat::sep_end_by((digit(), digit(), digit()).map(|(a, b, c)| vec![a, b, c].into_iter().collect()), no_partial(string("::")))
.skip(no_partial(string("\r\n")))
}
let input = "123::456::789::\r\n";
let result = run_decoder(&input, seq, TestParser(Default::default()));
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), vec![vec!["123".to_string(), "456".to_string(), "789".to_string()]]);
}
}
#[test]
fn skip_count_min_max_test() {
let seq = vec![PartialOp::Limited(1)];
impl_decoder! { TestParser, String,
repeat::skip_count_min_max(1, 2, char('_')).skip(char('.')).map(|_| "".to_string())
}
let input = "_.";
let result = run_decoder(input, seq, TestParser::default());
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap(), [""]);
}
const WORDS_IN_README: usize = 773;
#[test]
fn decode_std() {
quickcheck(
(|ops: PartialWithErrors<GenNoErrors>| {
let buf = include_bytes!("../README.md");
let mut read = PartialRead::new(&buf[..], ops);
let mut decoder =
combine::stream::Decoder::<_, combine::stream::PointerOffset<_>>::new();
let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
assert_eq!(
combine::decode!(
decoder,
read,
{
let word = many1(satisfy(|b| !is_whitespace(b)));
sep_end_by(word, skip_many1(satisfy(is_whitespace)))
.map(|words: Vec<Vec<u8>>| words.len())
},
|input, _| combine::easy::Stream::from(input)
)
.map_err(From::from)
.map_err(
|err: combine::easy::Errors<u8, &[u8], combine::stream::PointerOffset<_>>| err
.map_position(|p| p.0)
),
Ok(WORDS_IN_README),
);
}) as fn(_) -> _,
)
}
#[test]
fn decode_tokio_02() {
quickcheck(
(|ops: PartialWithErrors<GenWouldBlock>| {
let buf = include_bytes!("../README.md");
let runtime = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
runtime.block_on(async {
let mut read = PartialAsyncRead::new(&buf[..], ops);
let mut decoder =
combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
assert_eq!(
combine::decode_tokio_02!(
decoder,
read,
{
let word = many1(satisfy(|b| !is_whitespace(b)));
sep_end_by(word, skip_many1(satisfy(is_whitespace)))
.map(|words: Vec<Vec<u8>>| words.len())
},
|input, _| combine::easy::Stream::from(input)
)
.map_err(From::from)
.map_err(
|err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
)
.map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
Ok(WORDS_IN_README),
);
})
}) as fn(_) -> _,
)
}
#[test]
fn decode_tokio_03() {
quickcheck(
(|ops: PartialWithErrors<GenWouldBlock>| {
let buf = include_bytes!("../README.md");
let runtime = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
runtime.block_on(async {
let mut read = PartialAsyncRead::new(&buf[..], ops);
let mut decoder =
combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
assert_eq!(
combine::decode_tokio_03!(
decoder,
read,
{
let word = many1(satisfy(|b| !is_whitespace(b)));
sep_end_by(word, skip_many1(satisfy(is_whitespace)))
.map(|words: Vec<Vec<u8>>| words.len())
},
|input, _| combine::easy::Stream::from(input)
)
.map_err(From::from)
.map_err(
|err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
)
.map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
Ok(WORDS_IN_README),
);
})
}) as fn(_) -> _,
)
}
#[test]
fn decode_tokio() {
quickcheck(
(|ops: PartialWithErrors<GenWouldBlock>| {
let buf = include_bytes!("../README.md");
let runtime = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
runtime.block_on(async {
let mut read = PartialAsyncRead::new(&buf[..], ops);
let mut decoder =
combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
assert_eq!(
combine::decode_tokio!(
decoder,
read,
{
let word = many1(satisfy(|b| !is_whitespace(b)));
sep_end_by(word, skip_many1(satisfy(is_whitespace)))
.map(|words: Vec<Vec<u8>>| words.len())
},
|input, _| combine::easy::Stream::from(input)
)
.map_err(From::from)
.map_err(
|err: combine::easy::Errors<u8, &[u8], _>| err.map_range(|r| r.to_owned())
)
.map_err(|err| err.map_position(|p| p.translate_position(&decoder.buffer()))),
Ok(WORDS_IN_README),
);
})
}) as fn(_) -> _,
)
}
#[test]
fn decode_async_std() {
quickcheck(
(|ops: PartialWithErrors<GenWouldBlock>| {
let buf = include_bytes!("../README.md");
async_std::task::block_on(async {
let mut read = FuturesPartialAsyncRead::new(&buf[..], ops);
let mut decoder =
combine::stream::Decoder::<_, combine::stream::PointerOffset<[u8]>>::new();
let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
assert_eq!(
combine::decode_futures_03!(
decoder,
read,
{
let word = many1(satisfy(|b| !is_whitespace(b)));
sep_end_by(word, skip_many1(satisfy(is_whitespace)))
.map(|words: Vec<Vec<u8>>| words.len())
},
|input, _| combine::easy::Stream::from(input),
)
.map_err(From::from)
.map_err(|err: combine::easy::Errors<u8, &[u8], _>| err),
Ok(WORDS_IN_README),
);
})
}) as fn(_) -> _,
)
}
#[tokio::test]
async fn decode_loop() {
use tokio::fs::File;
use combine::{
decode_tokio, many1, satisfy, skip_many1,
stream::{buf_reader::BufReader, Decoder},
};
let mut read = BufReader::new(File::open("README.md").await.unwrap());
let mut decoder = Decoder::new_bufferless();
let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
let mut count = 0;
loop {
// async block suppresses a warning about duplicate label
if async {
decode_tokio!(
decoder,
read,
many1(satisfy(|b| !is_whitespace(b))),
|input, _position| combine::easy::Stream::from(input),
)
.is_err()
}
.await
{
break;
}
count += 1;
{
if decode_tokio!(
decoder,
read,
skip_many1(satisfy(is_whitespace)),
|input, _position| combine::easy::Stream::from(input),
)
.is_err()
{
break;
}
}
}
assert_eq!(WORDS_IN_README, count);
}

116
vendor/combine/tests/buffered_stream.rs vendored Normal file
View File

@@ -0,0 +1,116 @@
#![cfg(feature = "std")]
use combine::{
attempt, choice, many, many1,
parser::{
char::{char, digit, spaces, string},
combinator::recognize,
},
sep_by, skip_many1,
stream::{
buffered,
easy::{self, Error, Errors},
position, IteratorStream,
},
Parser, Positioned,
};
#[test]
fn shared_stream_buffer() {
// Iterator that can't be cloned
let text = "10,222,3,44".chars().map(|c| {
if c.is_digit(10) {
(c as u8 + 1) as char
} else {
c
}
});
let buffer = buffered::Stream::new(position::Stream::new(IteratorStream::new(text)), 1);
let int: &mut dyn Parser<_, Output = _, PartialState = _> =
&mut many(digit()).map(|s: String| s.parse::<i64>().unwrap());
let result = sep_by(int, char(',')).parse(buffer).map(|t| t.0);
assert_eq!(result, Ok(vec![21, 333, 4, 55]));
}
#[test]
fn shared_stream_backtrack() {
let text = "apple,apple,ananas,orangeblah";
let mut iter = text.chars();
// Iterator that can't be cloned
let stream = buffered::Stream::new(position::Stream::new(IteratorStream::new(&mut iter)), 2);
let value: &mut dyn Parser<_, Output = _, PartialState = _> = &mut choice([
attempt(string("apple")),
attempt(string("orange")),
attempt(string("ananas")),
]);
let mut parser = sep_by(value, char(','));
let result = parser.parse(stream).map(|t| t.0);
assert_eq!(result, Ok(vec!["apple", "apple", "ananas", "orange"]));
}
#[test]
fn shared_stream_insufficent_backtrack() {
let text = "apple,apple,ananas,orangeblah";
let mut iter = text.chars();
// Iterator that can't be cloned
let stream = buffered::Stream::new(
easy::Stream(position::Stream::new(IteratorStream::new(&mut iter))),
1,
);
let value: &mut dyn Parser<_, Output = _, PartialState = _> = &mut choice([
attempt(string("apple")),
attempt(string("orange")),
attempt(string("ananas")),
]);
let mut parser = sep_by(value, char(','));
let result: Result<Vec<&str>, _> = parser.parse(stream).map(|t| t.0);
assert!(result.is_err());
assert!(
result
.as_ref()
.unwrap_err()
.errors
.iter()
.any(|err| *err == Error::Message("Backtracked to far".into())),
"{}",
result.unwrap_err()
);
}
/// Test which checks that a stream which has ended does not repeat the last token in some cases in
/// which case this test would loop forever
#[test]
fn always_output_end_of_input_after_end_of_input() {
let text = "10".chars();
let buffer = buffered::Stream::new(position::Stream::new(IteratorStream::new(text)), 1);
let int = many1(digit()).map(|s: String| s.parse::<i64>().unwrap());
let result = many(spaces().with(int)).parse(buffer).map(|t| t.0);
assert_eq!(result, Ok(vec![10]));
}
#[test]
fn position() {
let text = "10abc".chars();
let stream = buffered::Stream::new(position::Stream::new(IteratorStream::new(text)), 3);
assert_eq!(stream.position(), 0);
let result = many1::<Vec<_>, _, _>(digit()).parse(stream);
assert!(result.is_ok());
assert_eq!(result.unwrap().1.position(), 2);
}
#[test]
fn buffered_stream_recognize_issue_256() {
let mut parser = recognize::<String, _, _>(skip_many1(digit()));
let input = "12 ";
assert_eq!(
parser
.parse(buffered::Stream::new(easy::Stream(input), 1))
.map_err(|err| err.map_position(|pos| pos.translate_position(input))),
Err(Errors {
position: 2,
errors: vec![easy::Error::Message("Backtracked to far".into())]
})
);
}

673
vendor/combine/tests/parser.rs vendored Normal file
View File

@@ -0,0 +1,673 @@
use combine::{
parser::{
char::{digit, letter},
choice::choice,
combinator::not_followed_by,
range::range,
token::{any, eof, token, Token},
},
Parser,
};
#[test]
fn choice_empty() {
let mut parser = choice::<_, &mut [Token<&str>]>(&mut []);
let result_err = parser.parse("a");
assert!(result_err.is_err());
}
#[test]
fn tuple() {
let mut parser = (digit(), token(','), digit(), token(','), letter());
assert_eq!(parser.parse("1,2,z"), Ok((('1', ',', '2', ',', 'z'), "")));
}
#[test]
fn issue_99() {
let result = any().map(|_| ()).or(eof()).parse("");
assert!(result.is_ok(), "{:?}", result);
}
#[test]
fn not_followed_by_does_not_consume_any_input() {
let mut parser = not_followed_by(range("a")).map(|_| "").or(range("a"));
assert_eq!(parser.parse("a"), Ok(("a", "")));
let mut parser = range("a").skip(not_followed_by(range("aa")));
assert_eq!(parser.parse("aa"), Ok(("a", "a")));
assert!(parser.parse("aaa").is_err());
}
#[cfg(feature = "std")]
mod tests_std {
use super::*;
use combine::easy::{Error, Errors};
use combine::parser::byte::alpha_num;
use combine::parser::byte::bytes;
use combine::parser::byte::bytes_cmp;
use combine::parser::byte::num::be_u32;
use combine::parser::char::char;
use combine::parser::char::{string, string_cmp};
use combine::parser::combinator::no_partial;
use combine::parser::range;
use combine::parser::repeat::{skip_until, take_until};
use combine::stream::position;
use combine::stream::position::SourcePosition;
use combine::{
attempt, count, count_min_max, easy, many, optional, position, sep_by, sep_end_by1,
unexpected, value, EasyParser,
};
#[derive(Clone, PartialEq, Debug)]
struct CloneOnly {
s: String,
}
#[test]
fn token_clone_but_not_copy() {
// Verify we can use token() with a StreamSlice with an token type that is Clone but not
// Copy.
let input = &[
CloneOnly { s: "x".to_string() },
CloneOnly { s: "y".to_string() },
][..];
let result = token(CloneOnly { s: "x".to_string() }).easy_parse(input);
assert_eq!(
result,
Ok((
CloneOnly { s: "x".to_string() },
&[CloneOnly { s: "y".to_string() }][..]
))
);
}
#[test]
fn sep_by_committed_error() {
type TwoLettersList = Vec<(char, char)>;
let mut parser2 = sep_by((letter(), letter()), token(','));
let result_err: Result<(TwoLettersList, &str), easy::ParseError<&str>> =
parser2.easy_parse("a,bc");
assert!(result_err.is_err());
}
/// The expected combinator should retain only errors that are not `Expected`
#[test]
fn expected_retain_errors() {
let mut parser = digit()
.message("message")
.expected("N/A")
.expected("my expected digit");
assert_eq!(
parser.easy_parse(position::Stream::new("a")),
Err(Errors {
position: SourcePosition::default(),
errors: vec![
Error::Unexpected('a'.into()),
Error::Message("message".into()),
Error::Expected("my expected digit".into()),
],
})
);
}
#[test]
fn tuple_parse_error() {
let mut parser = (digit(), digit());
let result = parser.easy_parse(position::Stream::new("a"));
assert_eq!(
result,
Err(Errors {
position: SourcePosition::default(),
errors: vec![
Error::Unexpected('a'.into()),
Error::Expected("digit".into()),
],
})
);
}
#[test]
fn message_tests() {
// Ensure message adds to both committed and empty errors, interacting with parse_lazy and
// parse_stream correctly on either side
let input = "hi";
let mut ok = char('h').message("not expected");
let mut empty0 = char('o').message("expected message");
let mut empty1 = char('o').message("expected message").map(|x| x);
let mut empty2 = char('o').map(|x| x).message("expected message");
let mut committed0 = char('h').with(char('o')).message("expected message");
let mut committed1 = char('h')
.with(char('o'))
.message("expected message")
.map(|x| x);
let mut committed2 = char('h')
.with(char('o'))
.map(|x| x)
.message("expected message");
assert!(ok.easy_parse(position::Stream::new(input)).is_ok());
let empty_expected = Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('h'.into()),
Error::Expected('o'.into()),
Error::Message("expected message".into()),
],
});
let committed_expected = Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![
Error::Unexpected('i'.into()),
Error::Expected('o'.into()),
Error::Message("expected message".into()),
],
});
assert_eq!(
empty0.easy_parse(position::Stream::new(input)),
empty_expected
);
assert_eq!(
empty1.easy_parse(position::Stream::new(input)),
empty_expected
);
assert_eq!(
empty2.easy_parse(position::Stream::new(input)),
empty_expected
);
assert_eq!(
committed0.easy_parse(position::Stream::new(input)),
committed_expected
);
assert_eq!(
committed1.easy_parse(position::Stream::new(input)),
committed_expected
);
assert_eq!(
committed2.easy_parse(position::Stream::new(input)),
committed_expected
);
}
#[test]
fn expected_tests() {
// Ensure `expected` replaces only empty errors, interacting with parse_lazy and
// parse_stream correctly on either side
let input = "hi";
let mut ok = char('h').expected("not expected");
let mut empty0 = char('o').expected("expected message");
let mut empty1 = char('o').expected("expected message").map(|x| x);
let mut empty2 = char('o').map(|x| x).expected("expected message");
let mut committed0 = char('h').with(char('o')).expected("expected message");
let mut committed1 = char('h')
.with(char('o'))
.expected("expected message")
.map(|x| x);
let mut committed2 = char('h')
.with(char('o'))
.map(|x| x)
.expected("expected message");
assert!(ok.easy_parse(position::Stream::new(input)).is_ok());
let empty_expected = Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('h'.into()),
Error::Expected("expected message".into()),
],
});
let committed_expected = Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![Error::Unexpected('i'.into()), Error::Expected('o'.into())],
});
assert_eq!(
empty0.easy_parse(position::Stream::new(input)),
empty_expected
);
assert_eq!(
empty1.easy_parse(position::Stream::new(input)),
empty_expected
);
assert_eq!(
empty2.easy_parse(position::Stream::new(input)),
empty_expected
);
assert_eq!(
committed0.easy_parse(position::Stream::new(input)),
committed_expected
);
assert_eq!(
committed1.easy_parse(position::Stream::new(input)),
committed_expected
);
assert_eq!(
committed2.easy_parse(position::Stream::new(input)),
committed_expected
);
}
#[test]
fn try_tests() {
// Ensure attempt adds error messages exactly once
assert_eq!(
attempt(unexpected("test")).easy_parse(position::Stream::new("hi")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('h'.into()),
Error::Unexpected("test".into()),
],
})
);
assert_eq!(
attempt(char('h').with(unexpected("test"))).easy_parse(position::Stream::new("hi")),
Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![
Error::Unexpected('i'.into()),
Error::Unexpected("test".into()),
],
})
);
}
#[test]
fn sequence_error() {
let mut parser = (char('a'), char('b'), char('c'));
assert_eq!(
parser.easy_parse(position::Stream::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![Error::Unexpected('c'.into()), Error::Expected('a'.into())],
})
);
assert_eq!(
parser.easy_parse(position::Stream::new("ac")),
Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![Error::Unexpected('c'.into()), Error::Expected('b'.into())],
})
);
}
#[test]
fn optional_empty_ok_then_error() {
let mut parser = (optional(char('a')), char('b'));
assert_eq!(
parser.easy_parse(position::Stream::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('c'.into()),
Error::Expected('a'.into()),
Error::Expected('b'.into()),
],
})
);
}
#[test]
fn nested_optional_empty_ok_then_error() {
let mut parser = ((optional(char('a')), char('b')), char('c'));
assert_eq!(
parser.easy_parse(position::Stream::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Unexpected('c'.into()),
Error::Expected('a'.into()),
Error::Expected('b'.into()),
],
})
);
}
#[test]
fn committed_then_optional_empty_ok_then_error() {
let mut parser = (char('b'), optional(char('a')), char('b'));
assert_eq!(
parser.easy_parse(position::Stream::new("bc")),
Err(Errors {
position: SourcePosition { line: 1, column: 2 },
errors: vec![
Error::Unexpected('c'.into()),
Error::Expected('a'.into()),
Error::Expected('b'.into()),
],
})
);
}
#[test]
fn sequence_in_choice_parser_empty_err() {
let mut parser = choice((
(optional(char('a')), char('1')),
(optional(char('b')), char('2')).skip(char('d')),
));
assert_eq!(
parser.easy_parse(position::Stream::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Expected('a'.into()),
Error::Expected('1'.into()),
Error::Expected('b'.into()),
Error::Expected('2'.into()),
Error::Unexpected('c'.into()),
],
})
);
}
#[test]
fn sequence_in_choice_array_parser_empty_err() {
let mut parser = choice([
(optional(char('a')), char('1')),
(optional(char('b')), char('2')),
]);
assert_eq!(
parser.easy_parse(position::Stream::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Expected('a'.into()),
Error::Expected('1'.into()),
Error::Expected('b'.into()),
Error::Expected('2'.into()),
Error::Unexpected('c'.into()),
],
})
);
}
#[test]
fn sequence_in_choice_array_parser_empty_err_where_first_parser_delay_errors() {
let mut p1 = char('1');
let mut p2 = no_partial((optional(char('b')), char('2')).map(|t| t.1));
let mut parser =
choice::<_, [&mut dyn Parser<_, Output = _, PartialState = _>; 2]>([&mut p1, &mut p2]);
assert_eq!(
parser.easy_parse(position::Stream::new("c")),
Err(Errors {
position: SourcePosition { line: 1, column: 1 },
errors: vec![
Error::Expected('1'.into()),
Error::Expected('b'.into()),
Error::Expected('2'.into()),
Error::Unexpected('c'.into()),
],
})
);
}
#[test]
fn sep_end_by1_dont_eat_separator_twice() {
let mut parser = sep_end_by1(digit(), token(';'));
assert_eq!(parser.parse("1;;"), Ok((vec!['1'], ";")));
}
#[test]
fn count_min_max_empty_error() {
assert_eq!(
count_min_max(1, 1, char('a')).or(value(vec![])).parse("b"),
Ok((vec![], "b"))
);
}
#[test]
fn sequence_parser_resets_partial_state_issue_168() {
assert_eq!(
take_until::<String, _, _>(attempt((char('a'), char('b')))).parse("aaab"),
Ok((String::from("aa"), "ab"))
);
}
#[test]
fn parser_macro_must_impl_parse_mode_issue_168() {
assert_eq!(
skip_until(attempt((char('a'), char('b')))).parse("aaab"),
Ok(((), "ab"))
);
}
#[test]
fn recognize_parser_issue_168() {
assert_eq!(
range::recognize(skip_until(attempt((char('a'), char('b'))))).parse("aaab"),
Ok(("aa", "ab"))
);
}
#[test]
fn sequence_in_optional_report_delayed_error() {
assert_eq!(
optional(position().with(char('a')))
.skip(char('}'))
.easy_parse("b")
.map_err(|e| e.errors),
Err(vec![
Error::Unexpected('b'.into()),
Error::Expected('a'.into()),
Error::Expected('}'.into()),
]),
);
}
#[test]
fn sequence_in_optional_nested_report_delayed_error() {
assert_eq!(
optional(position().with(char('a')))
.skip(optional(position().with(char('c'))))
.skip(char('}'))
.easy_parse("b")
.map_err(|e| e.errors),
Err(vec![
Error::Unexpected('b'.into()),
Error::Expected('a'.into()),
Error::Expected('c'.into()),
Error::Expected('}'.into()),
]),
);
}
#[test]
fn sequence_in_optional_nested_2_report_delayed_error() {
assert_eq!(
(
char('{'),
optional(position().with(char('a')))
.skip(optional(position().with(char('c'))))
.skip(char('}'))
)
.easy_parse("{b")
.map_err(|e| e.errors),
Err(vec![
Error::Unexpected('b'.into()),
Error::Expected('a'.into()),
Error::Expected('c'.into()),
Error::Expected('}'.into()),
]),
);
}
macro_rules! sequence_many_test {
($many:expr, $seq:expr) => {
let mut parser = $seq($many(position().with(char('a'))), char('}'));
let expected_error = Err(vec![
Error::Unexpected('b'.into()),
Error::Expected('a'.into()),
Error::Expected('}'.into()),
]);
assert_eq!(
parser.easy_parse("ab").map_err(|e| e.errors),
expected_error,
);
};
}
#[test]
fn sequence_in_many_report_delayed_error() {
use combine::parser::{repeat, sequence};
sequence_many_test!(repeat::many::<Vec<_>, _, _>, sequence::skip);
sequence_many_test!(repeat::many1::<Vec<_>, _, _>, sequence::skip);
sequence_many_test!(repeat::many::<Vec<_>, _, _>, sequence::with);
sequence_many_test!(repeat::many1::<Vec<_>, _, _>, sequence::with);
sequence_many_test!(repeat::many::<Vec<_>, _, _>, |l, x| sequence::between(
l,
char('|'),
x,
));
sequence_many_test!(repeat::many1::<Vec<_>, _, _>, |l, x| sequence::between(
l,
char('|'),
x,
));
}
macro_rules! sequence_sep_by_test {
($many:expr, $seq:expr) => {
let mut parser = $seq($many(position().with(char('a')), char(',')), char('}'));
let expected_error = Err(vec![
Error::Unexpected('b'.into()),
Error::Expected(','.into()),
Error::Expected('}'.into()),
]);
assert_eq!(
parser.easy_parse("a,ab").map_err(|e| e.errors),
expected_error,
);
};
}
#[test]
fn sequence_in_sep_by_report_delayed_error() {
use combine::parser::{repeat, sequence};
sequence_sep_by_test!(repeat::sep_by::<Vec<_>, _, _, _>, sequence::skip);
sequence_sep_by_test!(repeat::sep_by1::<Vec<_>, _, _, _>, sequence::skip);
sequence_sep_by_test!(repeat::sep_by::<Vec<_>, _, _, _>, sequence::with);
sequence_sep_by_test!(repeat::sep_by1::<Vec<_>, _, _, _>, sequence::with);
}
#[test]
fn choice_compose_on_error() {
let ident = |s| attempt(string(s));
let mut parser = choice((ident("aa").skip(string(";")), choice((ident("cc"),))));
assert_eq!(
parser.easy_parse("c").map_err(|err| err.errors),
Err(vec![
Error::Unexpected('c'.into()),
Error::Expected("aa".into()),
Error::Unexpected("end of input".into()),
Error::Expected("cc".into()),
]),
);
}
#[test]
fn choice_compose_issue_175() {
let ident = |s| attempt(string(s));
let mut parser = many::<Vec<_>, _, _>(position().and(choice((
ident("aa").skip(string(";")),
choice((ident("bb"), ident("cc"))),
))))
.skip(string("."));
assert_eq!(
parser.easy_parse("c").map_err(|err| err.errors),
Err(vec![
Error::Unexpected('c'.into()),
Error::Expected("aa".into()),
Error::Expected("bb".into()),
Error::Expected("cc".into()),
]),
);
}
#[test]
fn test() {
let mut parser = (digit(), letter());
assert_eq!(
parser.easy_parse("11").map_err(|err| err.errors),
Err(vec![
Error::Unexpected('1'.into()),
Error::Expected("letter".into()),
]),
);
}
#[test]
fn lifetime_inference() {
fn _string(source: &str) {
range::take(1).or(string("a")).parse(source).ok();
range::take(1)
.or(string_cmp("a", |x, y| x == y))
.parse(source)
.ok();
let _: &'static str = string("a").parse(source).unwrap().0;
let _: &'static str = string_cmp("a", |x, y| x == y).parse(source).unwrap().0;
}
fn _bytes(source: &[u8]) {
range::take(1).or(bytes(&[0u8])).parse(source).ok();
range::take(1)
.or(bytes_cmp(&[0u8], |x, y| x == y))
.parse(source)
.ok();
let _: &'static [u8] = bytes(&[0u8]).parse(source).unwrap().0;
let _: &'static [u8] = bytes_cmp(&[0u8], |x, y| x == y).parse(source).unwrap().0;
}
}
#[test]
fn test_nested_count_overflow() {
let key = || count::<Vec<_>, _, _>(64, alpha_num());
let value_bytes =
|| be_u32().then_partial(|&mut size| count::<Vec<_>, _, _>(size as usize, any()));
let value_messages =
(be_u32(), be_u32()).then_partial(|&mut (_body_size, message_count)| {
count::<Vec<_>, _, _>(message_count as usize, value_bytes())
});
let put = (bytes(b"PUT"), key())
.map(|(_, key)| key)
.and(value_messages);
let parser = || put.map(|(_, messages)| messages);
let command = &b"PUTkey\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x04\xDE\xAD\xBE\xEF\x00\x00\x00\x02\xBE\xEF"[..];
let result = parser().parse(command).unwrap();
assert_eq!(2, result.0.len());
}
#[test]
fn not_followed_by_empty_error_issue_220() {
let mut parser = string("let").skip(not_followed_by(eof().map(|_| "EOF")));
assert_eq!(
parser.easy_parse("let").map_err(|err| err.errors),
Err(vec![]),
);
}
}

38
vendor/combine/tests/parser_macro.rs vendored Normal file
View File

@@ -0,0 +1,38 @@
#![allow(clippy::single_match)]
#[macro_use]
extern crate combine;
parser! {
pub fn test[Input]()(Input) -> ()
where [Input: ::combine::Stream<Token = char>]
{
use combine::parser::token::value;
let _ = ();
fn _test() { }
match Some(1) {
Some(_) => (),
None => (),
}
value(())
}
}
parser! {
pub fn test_that_parsers_with_unnamed_types_can_be_in_same_scope[Input]()(Input) -> ()
where [Input: ::combine::Stream<Token = char>]
{
use combine::parser::token::value;
value(())
}
}
#[test]
fn test_that_we_dont_need_imports_for_this_macro_to_work() {
test::<&str>();
test_that_parsers_with_unnamed_types_can_be_in_same_scope::<&str>();
}

186
vendor/combine/tests/support/mod.rs vendored Normal file
View File

@@ -0,0 +1,186 @@
#![allow(dead_code)]
use std::{
io,
marker::Unpin,
pin::Pin,
task::{self, Poll},
};
use {futures_03_dep::ready, partial_io::PartialOp};
pub struct PartialAsyncRead<R> {
inner: R,
ops: Box<dyn Iterator<Item = PartialOp> + Send>,
}
impl<R> PartialAsyncRead<R>
where
R: Unpin,
{
pub fn new<I>(inner: R, ops: I) -> Self
where
I: IntoIterator<Item = PartialOp>,
I::IntoIter: Send + 'static,
{
PartialAsyncRead {
inner,
ops: Box::new(ops.into_iter()),
}
}
}
impl<R> tokio_02_dep::io::AsyncRead for PartialAsyncRead<R>
where
R: tokio_02_dep::io::AsyncRead + Unpin,
{
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut task::Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
match self.ops.next() {
Some(PartialOp::Limited(n)) => {
let len = std::cmp::min(n, buf.len());
Pin::new(&mut self.inner).poll_read(cx, &mut buf[..len])
}
Some(PartialOp::Err(err)) => {
if err == io::ErrorKind::WouldBlock {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Err(io::Error::new(
err,
"error during read, generated by partial-io",
))
.into()
}
}
Some(PartialOp::Unlimited) | None => Pin::new(&mut self.inner).poll_read(cx, buf),
}
}
}
impl<R> tokio_03_dep::io::AsyncRead for PartialAsyncRead<R>
where
R: tokio_03_dep::io::AsyncRead + Unpin,
{
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut task::Context<'_>,
buf: &mut tokio_03_dep::io::ReadBuf<'_>,
) -> Poll<io::Result<()>> {
match self.ops.next() {
Some(PartialOp::Limited(n)) => {
let len = std::cmp::min(n, buf.remaining());
buf.initialize_unfilled();
let mut sub_buf = buf.take(len);
ready!(Pin::new(&mut self.inner).poll_read(cx, &mut sub_buf))?;
let filled = sub_buf.filled().len();
buf.advance(filled);
Poll::Ready(Ok(()))
}
Some(PartialOp::Err(err)) => {
if err == io::ErrorKind::WouldBlock {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Err(io::Error::new(
err,
"error during read, generated by partial-io",
))
.into()
}
}
Some(PartialOp::Unlimited) | None => Pin::new(&mut self.inner).poll_read(cx, buf),
}
}
}
impl<R> tokio_dep::io::AsyncRead for PartialAsyncRead<R>
where
R: tokio_dep::io::AsyncRead + Unpin,
{
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut task::Context<'_>,
buf: &mut tokio_dep::io::ReadBuf<'_>,
) -> Poll<io::Result<()>> {
match self.ops.next() {
Some(PartialOp::Limited(n)) => {
let len = std::cmp::min(n, buf.remaining());
buf.initialize_unfilled();
let mut sub_buf = buf.take(len);
ready!(Pin::new(&mut self.inner).poll_read(cx, &mut sub_buf))?;
let filled = sub_buf.filled().len();
buf.advance(filled);
Poll::Ready(Ok(()))
}
Some(PartialOp::Err(err)) => {
if err == io::ErrorKind::WouldBlock {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Err(io::Error::new(
err,
"error during read, generated by partial-io",
))
.into()
}
}
Some(PartialOp::Unlimited) | None => Pin::new(&mut self.inner).poll_read(cx, buf),
}
}
}
pub struct FuturesPartialAsyncRead<R> {
inner: R,
ops: Box<dyn Iterator<Item = PartialOp> + Send>,
}
impl<R> FuturesPartialAsyncRead<R>
where
R: crate::futures::io::AsyncRead + Unpin,
{
pub fn new<I>(inner: R, ops: I) -> Self
where
I: IntoIterator<Item = PartialOp>,
I::IntoIter: Send + 'static,
{
FuturesPartialAsyncRead {
inner,
ops: Box::new(ops.into_iter()),
}
}
}
impl<R> crate::futures::io::AsyncRead for FuturesPartialAsyncRead<R>
where
R: crate::futures::io::AsyncRead + Unpin,
{
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut task::Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
match self.ops.next() {
Some(PartialOp::Limited(n)) => {
let len = std::cmp::min(n, buf.len());
Pin::new(&mut self.inner).poll_read(cx, &mut buf[..len])
}
Some(PartialOp::Err(err)) => {
if err == io::ErrorKind::WouldBlock {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Err(io::Error::new(
err,
"error during read, generated by partial-io",
))
.into()
}
}
Some(PartialOp::Unlimited) | None => Pin::new(&mut self.inner).poll_read(cx, buf),
}
}
}