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

187
vendor/combine/examples/async.rs vendored Normal file
View File

@@ -0,0 +1,187 @@
#![cfg(feature = "std")]
#![cfg(feature = "tokio")]
use std::{cell::Cell, io::Cursor, rc::Rc, str};
use {futures_03_dep as futures, tokio_dep as tokio};
use {
bytes::{Buf, BytesMut},
combine::{
error::{ParseError, StreamError},
parser::{
byte::digit,
combinator::{any_partial_state, AnyPartialState},
range::{range, recognize, take},
},
skip_many, skip_many1,
stream::{easy, PartialStream, RangeStream, StreamErrorFor},
Parser,
},
futures::prelude::*,
partial_io::PartialOp,
tokio_util::codec::{Decoder, FramedRead},
};
// Workaround partial_io not working with tokio-0.2
#[path = "../tests/support/mod.rs"]
mod support;
use support::*;
pub struct LanguageServerDecoder {
state: AnyPartialState,
content_length_parses: Rc<Cell<i32>>,
}
impl Default for LanguageServerDecoder {
fn default() -> Self {
LanguageServerDecoder {
state: Default::default(),
content_length_parses: Rc::new(Cell::new(0)),
}
}
}
/// Parses blocks of data with length headers
///
/// ```
/// Content-Length: 18
///
/// { "some": "data" }
/// ```
// The `content_length_parses` parameter only exists to demonstrate that `content_length` only
// gets parsed once per message
fn decode_parser<'a, Input>(
content_length_parses: Rc<Cell<i32>>,
) -> impl Parser<Input, Output = Vec<u8>, PartialState = AnyPartialState> + 'a
where
Input: RangeStream<Token = u8, Range = &'a [u8]> + 'a,
{
let content_length = range(&b"Content-Length: "[..])
.with(recognize(skip_many1(digit())).and_then(|digits: &[u8]| {
str::from_utf8(digits)
.unwrap()
.parse::<usize>()
// Convert the error from `.parse` into an error combine understands
.map_err(StreamErrorFor::<Input>::other)
}))
.map(move |x| {
content_length_parses.set(content_length_parses.get() + 1);
x
});
// `any_partial_state` boxes the state which hides the type and lets us store it in
// `self`
any_partial_state(
(
skip_many(range(&b"\r\n"[..])),
content_length,
range(&b"\r\n\r\n"[..]).map(|_| ()),
)
.then_partial(|&mut (_, message_length, _)| {
take(message_length).map(|bytes: &[u8]| bytes.to_owned())
}),
)
}
impl Decoder for LanguageServerDecoder {
type Item = String;
type Error = Box<dyn std::error::Error + Send + Sync>;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
println!("Decoding `{:?}`", str::from_utf8(src).unwrap_or("NOT UTF8"));
let (opt, removed_len) = combine::stream::decode(
decode_parser(self.content_length_parses.clone()),
// easy::Stream gives us nice error messages
// (the same error messages that combine has had since its inception)
// PartialStream lets the parser know that more input should be
// expected if end of input is unexpectedly reached
&mut easy::Stream(PartialStream(&src[..])),
&mut self.state,
)
.map_err(|err| {
// Since err contains references into `src` we must replace these before
// we can return an error or call `advance` to remove the input we
// just committed
let err = err
.map_range(|r| {
str::from_utf8(r)
.ok()
.map_or_else(|| format!("{:?}", r), |s| s.to_string())
})
.map_position(|p| p.translate_position(&src[..]));
format!("{}\nIn input: `{}`", err, str::from_utf8(src).unwrap())
})?;
println!(
"Accepted {} bytes: `{:?}`",
removed_len,
str::from_utf8(&src[..removed_len]).unwrap_or("NOT UTF8")
);
// Remove the input we just committed.
// Ideally this would be done automatically by the call to
// `stream::decode` but it does unfortunately not work due
// to lifetime issues (Non lexical lifetimes might fix it!)
src.advance(removed_len);
match opt {
// `None` means we did not have enough input and we require that the
// caller of `decode` supply more before calling us again
None => {
println!("Requesting more input!");
Ok(None)
}
// `Some` means that a message was successfully decoded
// (and that we are ready to start decoding the next message)
Some(output) => {
let value = String::from_utf8(output)?;
println!("Decoded `{}`", value);
Ok(Some(value))
}
}
}
}
#[tokio::main]
async fn main() {
let input = "Content-Length: 6\r\n\
\r\n\
123456\r\n\
Content-Length: 4\r\n\
\r\n\
true";
let seq = vec![
PartialOp::Limited(20),
PartialOp::Limited(1),
PartialOp::Limited(2),
PartialOp::Limited(3),
];
let reader = &mut Cursor::new(input.as_bytes());
// Using the `partial_io` crate we emulate the partial reads that would happen when reading
// asynchronously from an io device.
let partial_reader = PartialAsyncRead::new(reader, seq);
let decoder = LanguageServerDecoder::default();
let content_length_parses = decoder.content_length_parses.clone();
let result = FramedRead::new(partial_reader, decoder).try_collect().await;
assert!(result.as_ref().is_ok(), "{}", result.unwrap_err());
let values: Vec<_> = result.unwrap();
let expected_values = ["123456", "true"];
assert_eq!(values, expected_values);
assert_eq!(content_length_parses.get(), expected_values.len() as i32);
println!("Successfully parsed: `{}`", input);
println!(
"Found {} items and never repeated a completed parse!",
values.len(),
);
println!("Result: {:?}", values);
}

228
vendor/combine/examples/date.rs vendored Normal file
View File

@@ -0,0 +1,228 @@
//! Parser example for ISO8601 dates. This does not handle the entire specification but it should
//! show the gist of it and be easy to extend to parse additional forms.
use std::{
env, fmt,
fs::File,
io::{self, Read},
};
use combine::{
choice,
many, optional,
parser::char::{char, digit},
stream::position,
Parser, Stream,
};
#[cfg(feature = "std")]
use combine::{
stream::{easy, position::SourcePosition},
EasyParser,
};
enum Error<E> {
Io(io::Error),
Parse(E),
}
impl<E> fmt::Display for Error<E>
where
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Error::Io(ref err) => write!(f, "{}", err),
Error::Parse(ref err) => write!(f, "{}", err),
}
}
}
#[derive(PartialEq, Debug)]
pub struct Date {
pub year: i32,
pub month: i32,
pub day: i32,
}
#[derive(PartialEq, Debug)]
pub struct Time {
pub hour: i32,
pub minute: i32,
pub second: i32,
pub time_zone: i32,
}
#[derive(PartialEq, Debug)]
pub struct DateTime {
pub date: Date,
pub time: Time,
}
fn two_digits<Input>() -> impl Parser<Input, Output = i32>
where
Input: Stream<Token = char>,
{
(digit(), digit()).map(|(x, y): (char, char)| {
let x = x.to_digit(10).expect("digit");
let y = y.to_digit(10).expect("digit");
(x * 10 + y) as i32
})
}
/// Parses a time zone
/// +0012
/// -06:30
/// -01
/// Z
fn time_zone<Input>() -> impl Parser<Input, Output = i32>
where
Input: Stream<Token = char>,
{
let utc = char('Z').map(|_| 0);
let offset = (
choice([char('-'), char('+')]),
two_digits(),
optional(optional(char(':')).with(two_digits())),
)
.map(|(sign, hour, minute)| {
let offset = hour * 60 + minute.unwrap_or(0);
if sign == '-' {
-offset
} else {
offset
}
});
utc.or(offset)
}
/// Parses a date
/// 2010-01-30
fn date<Input>() -> impl Parser<Input, Output = Date>
where
Input: Stream<Token = char>,
{
(
many::<String, _, _>(digit()),
char('-'),
two_digits(),
char('-'),
two_digits(),
)
.map(|(year, _, month, _, day)| {
// Its ok to just unwrap since we only parsed digits
Date {
year: year.parse().unwrap(),
month,
day,
}
})
}
/// Parses a time
/// 12:30:02
fn time<Input>() -> impl Parser<Input, Output = Time>
where
Input: Stream<Token = char>,
{
(
two_digits(),
char(':'),
two_digits(),
char(':'),
two_digits(),
time_zone(),
)
.map(|(hour, _, minute, _, second, time_zone)| {
// Its ok to just unwrap since we only parsed digits
Time {
hour,
minute,
second,
time_zone,
}
})
}
/// Parses a date time according to ISO8601
/// 2015-08-02T18:54:42+02
fn date_time<Input>() -> impl Parser<Input, Output = DateTime>
where
Input: Stream<Token = char>,
{
(date(), char('T'), time()).map(|(date, _, time)| DateTime { date, time })
}
#[test]
fn test() {
// A parser for
let result = date_time().parse("2015-08-02T18:54:42+02");
let d = DateTime {
date: Date {
year: 2015,
month: 8,
day: 2,
},
time: Time {
hour: 18,
minute: 54,
second: 42,
time_zone: 2 * 60,
},
};
assert_eq!(result, Ok((d, "")));
let result = date_time().parse("50015-12-30T08:54:42Z");
let d = DateTime {
date: Date {
year: 50015,
month: 12,
day: 30,
},
time: Time {
hour: 8,
minute: 54,
second: 42,
time_zone: 0,
},
};
assert_eq!(result, Ok((d, "")));
}
fn main() {
let result = match env::args().nth(1) {
Some(file) => File::open(file).map_err(Error::Io).and_then(main_),
None => main_(io::stdin()),
};
match result {
Ok(_) => println!("OK"),
Err(err) => println!("{}", err),
}
}
#[cfg(feature = "std")]
fn main_<R>(mut read: R) -> Result<(), Error<easy::Errors<char, String, SourcePosition>>>
where
R: Read,
{
let mut text = String::new();
read.read_to_string(&mut text).map_err(Error::Io)?;
date_time()
.easy_parse(position::Stream::new(&*text))
.map_err(|err| Error::Parse(err.map_range(|s| s.to_string())))?;
Ok(())
}
#[cfg(not(feature = "std"))]
fn main_<R>(mut read: R) -> Result<(), Error<::combine::error::StringStreamError>>
where
R: Read,
{
let mut text = String::new();
read.read_to_string(&mut text).map_err(Error::Io)?;
date_time()
.parse(position::Stream::new(&*text))
.map_err(Error::Parse)?;
Ok(())
}

173
vendor/combine/examples/ini.rs vendored Normal file
View File

@@ -0,0 +1,173 @@
//! Parser example for INI files.
use std::{
collections::HashMap,
env, fmt,
fs::File,
io::{self, Read},
};
use combine::{parser::char::space, stream::position, *};
#[cfg(feature = "std")]
use combine::stream::easy;
#[cfg(feature = "std")]
use combine::stream::position::SourcePosition;
enum Error<E> {
Io(io::Error),
Parse(E),
}
impl<E> fmt::Display for Error<E>
where
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Error::Io(ref err) => write!(f, "{}", err),
Error::Parse(ref err) => write!(f, "{}", err),
}
}
}
#[derive(PartialEq, Debug)]
pub struct Ini {
pub global: HashMap<String, String>,
pub sections: HashMap<String, HashMap<String, String>>,
}
fn property<Input>() -> impl Parser<Input, Output = (String, String)>
where
Input: Stream<Token = char>,
{
(
many1(satisfy(|c| c != '=' && c != '[' && c != ';')),
token('='),
many1(satisfy(|c| c != '\n' && c != ';')),
)
.map(|(key, _, value)| (key, value))
.message("while parsing property")
}
fn whitespace<Input>() -> impl Parser<Input>
where
Input: Stream<Token = char>,
{
let comment = (token(';'), skip_many(satisfy(|c| c != '\n'))).map(|_| ());
// Wrap the `spaces().or(comment)` in `skip_many` so that it skips alternating whitespace and
// comments
skip_many(skip_many1(space()).or(comment))
}
fn properties<Input>() -> impl Parser<Input, Output = HashMap<String, String>>
where
Input: Stream<Token = char>,
{
// After each property we skip any whitespace that followed it
many(property().skip(whitespace()))
}
fn section<Input>() -> impl Parser<Input, Output = (String, HashMap<String, String>)>
where
Input: Stream<Token = char>,
{
(
between(token('['), token(']'), many(satisfy(|c| c != ']'))),
whitespace(),
properties(),
)
.map(|(name, _, properties)| (name, properties))
.message("while parsing section")
}
fn ini<Input>() -> impl Parser<Input, Output = Ini>
where
Input: Stream<Token = char>,
{
(whitespace(), properties(), many(section()))
.map(|(_, global, sections)| Ini { global, sections })
}
#[test]
fn ini_ok() {
let text = r#"
language=rust
[section]
name=combine; Comment
type=LL(1)
"#;
let mut expected = Ini {
global: HashMap::new(),
sections: HashMap::new(),
};
expected
.global
.insert(String::from("language"), String::from("rust"));
let mut section = HashMap::new();
section.insert(String::from("name"), String::from("combine"));
section.insert(String::from("type"), String::from("LL(1)"));
expected.sections.insert(String::from("section"), section);
let result = ini().parse(text).map(|t| t.0);
assert_eq!(result, Ok(expected));
}
#[cfg(feature = "std")]
#[test]
fn ini_error() {
let text = "[error";
let result = ini().easy_parse(position::Stream::new(text)).map(|t| t.0);
assert_eq!(
result,
Err(easy::Errors {
position: SourcePosition { line: 1, column: 7 },
errors: vec![
easy::Error::end_of_input(),
easy::Error::Expected(']'.into()),
easy::Error::Message("while parsing section".into()),
],
})
);
}
fn main() {
let result = match env::args().nth(1) {
Some(file) => File::open(file).map_err(Error::Io).and_then(main_),
None => main_(io::stdin()),
};
match result {
Ok(_) => println!("OK"),
Err(err) => println!("{}", err),
}
}
#[cfg(feature = "std")]
fn main_<R>(mut read: R) -> Result<(), Error<easy::Errors<char, String, SourcePosition>>>
where
R: Read,
{
let mut text = String::new();
read.read_to_string(&mut text).map_err(Error::Io)?;
ini()
.easy_parse(position::Stream::new(&*text))
.map_err(|err| Error::Parse(err.map_range(|s| s.to_string())))?;
Ok(())
}
#[cfg(not(feature = "std"))]
fn main_<R>(mut read: R) -> Result<(), Error<::combine::error::StringStreamError>>
where
R: Read,
{
let mut text = String::new();
read.read_to_string(&mut text).map_err(Error::Io)?;
ini()
.parse(position::Stream::new(&*text))
.map_err(Error::Parse)?;
Ok(())
}

33
vendor/combine/examples/number.rs vendored Normal file
View File

@@ -0,0 +1,33 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
use core::str;
#[cfg(feature = "std")]
use std::str;
use combine::{
error::UnexpectedParse,
parser::{
byte::digit,
choice::optional,
range::recognize,
repeat::{skip_many, skip_many1},
token::token,
},
Parser,
};
fn main() {
let mut parser = recognize((
skip_many1(digit()),
optional((token(b'.'), skip_many(digit()))),
))
.and_then(|bs: &[u8]| {
// `bs` only contains digits which are ascii and thus UTF-8
let s = unsafe { str::from_utf8_unchecked(bs) };
s.parse::<f64>().map_err(|_| UnexpectedParse::Unexpected)
});
let result = parser.parse(&b"123.45"[..]);
assert_eq!(result, Ok((123.45, &b""[..])));
}

18
vendor/combine/examples/readme.rs vendored Normal file
View File

@@ -0,0 +1,18 @@
use combine::{
many1,
parser::char::{letter, space},
sep_by, Parser,
};
#[test]
fn readme() {
main();
}
fn main() {
let word = many1(letter());
let mut parser = sep_by(word, space()).map(|mut words: Vec<String>| words.pop());
let result = parser.parse("Pick up that word!");
assert_eq!(result, Ok((Some("word".to_string()), "!")));
}