#[cfg(test)]
mod tests;
use crate::error::ErrorKind;
use crate::error::ParseError;
use crate::internal::{Err, IResult, Needed, Parser};
#[cfg(feature = "alloc")]
use crate::lib::std::vec::Vec;
use crate::traits::{InputLength, InputTake, ToUsize};
use core::num::NonZeroUsize;
#[cfg(feature = "alloc")]
const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn many0<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |mut i: I| {
let mut acc = crate::lib::std::vec::Vec::with_capacity(4);
loop {
let len = i.input_len();
match f.parse(i.clone()) {
Err(Err::Error(_)) => return Ok((i, acc)),
Err(e) => return Err(e),
Ok((i1, o)) => {
if i1.input_len() == len {
return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many0)));
}
i = i1;
acc.push(o);
}
}
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn many1<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |mut i: I| match f.parse(i.clone()) {
Err(Err::Error(err)) => Err(Err::Error(E::append(i, ErrorKind::Many1, err))),
Err(e) => Err(e),
Ok((i1, o)) => {
let mut acc = crate::lib::std::vec::Vec::with_capacity(4);
acc.push(o);
i = i1;
loop {
let len = i.input_len();
match f.parse(i.clone()) {
Err(Err::Error(_)) => return Ok((i, acc)),
Err(e) => return Err(e),
Ok((i1, o)) => {
if i1.input_len() == len {
return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1)));
}
i = i1;
acc.push(o);
}
}
}
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn many_till<I, O, P, E, F, G>(
mut f: F,
mut g: G,
) -> impl FnMut(I) -> IResult<I, (Vec<O>, P), E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
G: Parser<I, P, E>,
E: ParseError<I>,
{
move |mut i: I| {
let mut res = crate::lib::std::vec::Vec::new();
loop {
let len = i.input_len();
match g.parse(i.clone()) {
Ok((i1, o)) => return Ok((i1, (res, o))),
Err(Err::Error(_)) => {
match f.parse(i.clone()) {
Err(Err::Error(err)) => return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))),
Err(e) => return Err(e),
Ok((i1, o)) => {
if i1.input_len() == len {
return Err(Err::Error(E::from_error_kind(i1, ErrorKind::ManyTill)));
}
res.push(o);
i = i1;
}
}
}
Err(e) => return Err(e),
}
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn separated_list0<I, O, O2, E, F, G>(
mut sep: G,
mut f: F,
) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
G: Parser<I, O2, E>,
E: ParseError<I>,
{
move |mut i: I| {
let mut res = Vec::new();
match f.parse(i.clone()) {
Err(Err::Error(_)) => return Ok((i, res)),
Err(e) => return Err(e),
Ok((i1, o)) => {
res.push(o);
i = i1;
}
}
loop {
let len = i.input_len();
match sep.parse(i.clone()) {
Err(Err::Error(_)) => return Ok((i, res)),
Err(e) => return Err(e),
Ok((i1, _)) => {
if i1.input_len() == len {
return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList)));
}
match f.parse(i1.clone()) {
Err(Err::Error(_)) => return Ok((i, res)),
Err(e) => return Err(e),
Ok((i2, o)) => {
res.push(o);
i = i2;
}
}
}
}
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn separated_list1<I, O, O2, E, F, G>(
mut sep: G,
mut f: F,
) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
G: Parser<I, O2, E>,
E: ParseError<I>,
{
move |mut i: I| {
let mut res = Vec::new();
match f.parse(i.clone()) {
Err(e) => return Err(e),
Ok((i1, o)) => {
res.push(o);
i = i1;
}
}
loop {
let len = i.input_len();
match sep.parse(i.clone()) {
Err(Err::Error(_)) => return Ok((i, res)),
Err(e) => return Err(e),
Ok((i1, _)) => {
if i1.input_len() == len {
return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList)));
}
match f.parse(i1.clone()) {
Err(Err::Error(_)) => return Ok((i, res)),
Err(e) => return Err(e),
Ok((i2, o)) => {
res.push(o);
i = i2;
}
}
}
}
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn many_m_n<I, O, E, F>(
min: usize,
max: usize,
mut parse: F,
) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |mut input: I| {
if min > max {
return Err(Err::Failure(E::from_error_kind(input, ErrorKind::ManyMN)));
}
let max_initial_capacity =
MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<O>().max(1);
let mut res = crate::lib::std::vec::Vec::with_capacity(min.min(max_initial_capacity));
for count in 0..max {
let len = input.input_len();
match parse.parse(input.clone()) {
Ok((tail, value)) => {
if tail.input_len() == len {
return Err(Err::Error(E::from_error_kind(input, ErrorKind::ManyMN)));
}
res.push(value);
input = tail;
}
Err(Err::Error(e)) => {
if count < min {
return Err(Err::Error(E::append(input, ErrorKind::ManyMN, e)));
} else {
return Ok((input, res));
}
}
Err(e) => {
return Err(e);
}
}
}
Ok((input, res))
}
}
pub fn many0_count<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, usize, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |i: I| {
let mut input = i;
let mut count = 0;
loop {
let input_ = input.clone();
let len = input.input_len();
match f.parse(input_) {
Ok((i, _)) => {
if i.input_len() == len {
return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0Count)));
}
input = i;
count += 1;
}
Err(Err::Error(_)) => return Ok((input, count)),
Err(e) => return Err(e),
}
}
}
}
pub fn many1_count<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, usize, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |i: I| {
let i_ = i.clone();
match f.parse(i_) {
Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count))),
Err(i) => Err(i),
Ok((i1, _)) => {
let mut count = 1;
let mut input = i1;
loop {
let len = input.input_len();
let input_ = input.clone();
match f.parse(input_) {
Err(Err::Error(_)) => return Ok((input, count)),
Err(e) => return Err(e),
Ok((i, _)) => {
if i.input_len() == len {
return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count)));
}
count += 1;
input = i;
}
}
}
}
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn count<I, O, E, F>(mut f: F, count: usize) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone + PartialEq,
F: Parser<I, O, E>,
E: ParseError<I>,
{
move |i: I| {
let mut input = i.clone();
let max_initial_capacity =
MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<O>().max(1);
let mut res = crate::lib::std::vec::Vec::with_capacity(count.min(max_initial_capacity));
for _ in 0..count {
let input_ = input.clone();
match f.parse(input_) {
Ok((i, o)) => {
res.push(o);
input = i;
}
Err(Err::Error(e)) => {
return Err(Err::Error(E::append(i, ErrorKind::Count, e)));
}
Err(e) => {
return Err(e);
}
}
}
Ok((input, res))
}
}
pub fn fill<'a, I, O, E, F>(f: F, buf: &'a mut [O]) -> impl FnMut(I) -> IResult<I, (), E> + 'a
where
I: Clone + PartialEq,
F: Fn(I) -> IResult<I, O, E> + 'a,
E: ParseError<I>,
{
move |i: I| {
let mut input = i.clone();
for elem in buf.iter_mut() {
let input_ = input.clone();
match f(input_) {
Ok((i, o)) => {
*elem = o;
input = i;
}
Err(Err::Error(e)) => {
return Err(Err::Error(E::append(i, ErrorKind::Count, e)));
}
Err(e) => {
return Err(e);
}
}
}
Ok((input, ()))
}
}
pub fn fold_many0<I, O, E, F, G, H, R>(
mut f: F,
mut init: H,
mut g: G,
) -> impl FnMut(I) -> IResult<I, R, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
G: FnMut(R, O) -> R,
H: FnMut() -> R,
E: ParseError<I>,
{
move |i: I| {
let mut res = init();
let mut input = i;
loop {
let i_ = input.clone();
let len = input.input_len();
match f.parse(i_) {
Ok((i, o)) => {
if i.input_len() == len {
return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0)));
}
res = g(res, o);
input = i;
}
Err(Err::Error(_)) => {
return Ok((input, res));
}
Err(e) => {
return Err(e);
}
}
}
}
}
pub fn fold_many1<I, O, E, F, G, H, R>(
mut f: F,
mut init: H,
mut g: G,
) -> impl FnMut(I) -> IResult<I, R, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
G: FnMut(R, O) -> R,
H: FnMut() -> R,
E: ParseError<I>,
{
move |i: I| {
let _i = i.clone();
let init = init();
match f.parse(_i) {
Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))),
Err(e) => Err(e),
Ok((i1, o1)) => {
let mut acc = g(init, o1);
let mut input = i1;
loop {
let _input = input.clone();
let len = input.input_len();
match f.parse(_input) {
Err(Err::Error(_)) => {
break;
}
Err(e) => return Err(e),
Ok((i, o)) => {
if i.input_len() == len {
return Err(Err::Failure(E::from_error_kind(i, ErrorKind::Many1)));
}
acc = g(acc, o);
input = i;
}
}
}
Ok((input, acc))
}
}
}
}
pub fn fold_many_m_n<I, O, E, F, G, H, R>(
min: usize,
max: usize,
mut parse: F,
mut init: H,
mut fold: G,
) -> impl FnMut(I) -> IResult<I, R, E>
where
I: Clone + InputLength,
F: Parser<I, O, E>,
G: FnMut(R, O) -> R,
H: FnMut() -> R,
E: ParseError<I>,
{
move |mut input: I| {
if min > max {
return Err(Err::Failure(E::from_error_kind(input, ErrorKind::ManyMN)));
}
let mut acc = init();
for count in 0..max {
let len = input.input_len();
match parse.parse(input.clone()) {
Ok((tail, value)) => {
if tail.input_len() == len {
return Err(Err::Error(E::from_error_kind(tail, ErrorKind::ManyMN)));
}
acc = fold(acc, value);
input = tail;
}
Err(Err::Error(err)) => {
if count < min {
return Err(Err::Error(E::append(input, ErrorKind::ManyMN, err)));
} else {
break;
}
}
Err(e) => return Err(e),
}
}
Ok((input, acc))
}
}
pub fn length_data<I, N, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, I, E>
where
I: InputLength + InputTake,
N: ToUsize,
F: Parser<I, N, E>,
E: ParseError<I>,
{
move |i: I| {
let (i, length) = f.parse(i)?;
let length: usize = length.to_usize();
if let Some(needed) = length
.checked_sub(i.input_len())
.and_then(NonZeroUsize::new)
{
Err(Err::Incomplete(Needed::Size(needed)))
} else {
Ok(i.take_split(length))
}
}
}
pub fn length_value<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, O, E>
where
I: Clone + InputLength + InputTake,
N: ToUsize,
F: Parser<I, N, E>,
G: Parser<I, O, E>,
E: ParseError<I>,
{
move |i: I| {
let (i, length) = f.parse(i)?;
let length: usize = length.to_usize();
if let Some(needed) = length
.checked_sub(i.input_len())
.and_then(NonZeroUsize::new)
{
Err(Err::Incomplete(Needed::Size(needed)))
} else {
let (rest, i) = i.take_split(length);
match g.parse(i.clone()) {
Err(Err::Incomplete(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))),
Err(e) => Err(e),
Ok((_, o)) => Ok((rest, o)),
}
}
}
}
#[cfg(feature = "alloc")]
pub fn length_count<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, Vec<O>, E>
where
I: Clone,
N: ToUsize,
F: Parser<I, N, E>,
G: Parser<I, O, E>,
E: ParseError<I>,
{
move |i: I| {
let (i, count) = f.parse(i)?;
let mut input = i.clone();
let mut res = Vec::new();
for _ in 0..count.to_usize() {
let input_ = input.clone();
match g.parse(input_) {
Ok((i, o)) => {
res.push(o);
input = i;
}
Err(Err::Error(e)) => {
return Err(Err::Error(E::append(i, ErrorKind::Count, e)));
}
Err(e) => {
return Err(e);
}
}
}
Ok((input, res))
}
}