Skip to content

Commit

Permalink
Use the Input trait in parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Jan 5, 2023
1 parent 76b0f73 commit 110261a
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 945 deletions.
13 changes: 8 additions & 5 deletions src/bits/complete.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! Bit level parsers
//!

use core::ops::RangeFrom;

use crate::error::{ErrorKind, ParseError};
use crate::internal::{Err, IResult};
use crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr};
use crate::traits::{InputIter, InputLength, Slice, ToUsize};
use crate::lib::std::ops::{AddAssign, Div, Shl, Shr};
use crate::traits::{Input, ToUsize};
use crate::Slice;

/// Generates a parser taking `count` bits
///
Expand Down Expand Up @@ -34,7 +37,7 @@ pub fn take<I, O, C, E: ParseError<(I, usize)>>(
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
I: Input<Item = u8> + Slice<RangeFrom<usize>>,
C: ToUsize,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
{
Expand Down Expand Up @@ -87,7 +90,7 @@ pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
I: Input<Item = u8> + Clone + Slice<RangeFrom<usize>>,
C: ToUsize,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq,
{
Expand Down Expand Up @@ -122,7 +125,7 @@ where
/// ```
pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
I: Input<Item = u8> + Slice<RangeFrom<usize>>,
{
let (res, bit): (_, u32) = take(1usize)(input)?;
Ok((res, bit != 0))
Expand Down
12 changes: 7 additions & 5 deletions src/bits/streaming.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
//! Bit level parsers
//!

use core::ops::RangeFrom;

use crate::error::{ErrorKind, ParseError};
use crate::internal::{Err, IResult, Needed};
use crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr};
use crate::traits::{InputIter, InputLength, Slice, ToUsize};
use crate::lib::std::ops::{AddAssign, Div, Shl, Shr};
use crate::traits::{Input, Slice, ToUsize};

/// Generates a parser taking `count` bits
pub fn take<I, O, C, E: ParseError<(I, usize)>>(
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
I: Input<Item = u8> + Slice<RangeFrom<usize>>,
C: ToUsize,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>,
{
Expand Down Expand Up @@ -61,7 +63,7 @@ pub fn tag<I, O, C, E: ParseError<(I, usize)>>(
count: C,
) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone,
I: Input<Item = u8> + Clone + Slice<RangeFrom<usize>>,
C: ToUsize,
O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq,
{
Expand Down Expand Up @@ -96,7 +98,7 @@ where
/// ```
pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E>
where
I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
I: Input<Item = u8> + Slice<RangeFrom<usize>>,
{
let (res, bit): (_, u32) = take(1usize)(input)?;
Ok((res, bit != 0))
Expand Down
160 changes: 63 additions & 97 deletions src/bytes/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use crate::internal::{Err, IResult, Parser};
use crate::lib::std::ops::RangeFrom;
use crate::lib::std::result::Result::*;
use crate::traits::{
Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
InputTakeAtPosition, Slice, ToUsize,
Compare, CompareResult, FindSubstring, FindToken, InputLength, Slice, ToUsize,
};
use crate::Input;

/// Recognizes a pattern
///
Expand All @@ -29,14 +29,12 @@ use crate::traits::{
/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag))));
/// ```
pub fn tag<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn tag<T, I, Error: ParseError<I>>(tag: T) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTake + Compare<T>,
I: Input + Compare<T>,
T: InputLength + Clone,
{
move |i: Input| {
move |i: I| {
let tag_len = tag.input_len();
let t = tag.clone();
let res: IResult<_, _, Error> = match i.compare(t) {
Expand Down Expand Up @@ -71,14 +69,12 @@ where
/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag))));
/// ```
pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn tag_no_case<T, I, Error: ParseError<I>>(tag: T) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTake + Compare<T>,
I: Input + Compare<T>,
T: InputLength + Clone,
{
move |i: Input| {
move |i: I| {
let tag_len = tag.input_len();
let t = tag.clone();

Expand Down Expand Up @@ -114,14 +110,12 @@ where
/// assert_eq!(not_space("Nospace"), Ok(("", "Nospace")));
/// assert_eq!(not_space(""), Err(Err::Error(Error::new("", ErrorKind::IsNot))));
/// ```
pub fn is_not<T, Input, Error: ParseError<Input>>(
arr: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn is_not<T, I, Error: ParseError<I>>(arr: T) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTakeAtPosition,
T: FindToken<<Input as InputTakeAtPosition>::Item>,
I: Input,
T: FindToken<<I as Input>::Item>,
{
move |i: Input| {
move |i: I| {
let e: ErrorKind = ErrorKind::IsNot;
i.split_at_position1_complete(|c| arr.find_token(c), e)
}
Expand All @@ -148,14 +142,12 @@ where
/// assert_eq!(hex("D15EA5E"), Ok(("", "D15EA5E")));
/// assert_eq!(hex(""), Err(Err::Error(Error::new("", ErrorKind::IsA))));
/// ```
pub fn is_a<T, Input, Error: ParseError<Input>>(
arr: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn is_a<T, I, Error: ParseError<I>>(arr: T) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTakeAtPosition,
T: FindToken<<Input as InputTakeAtPosition>::Item>,
I: Input,
T: FindToken<<I as Input>::Item>,
{
move |i: Input| {
move |i: I| {
let e: ErrorKind = ErrorKind::IsA;
i.split_at_position1_complete(|c| !arr.find_token(c), e)
}
Expand All @@ -180,14 +172,12 @@ where
/// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
/// assert_eq!(alpha(b""), Ok((&b""[..], &b""[..])));
/// ```
pub fn take_while<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
I: Input,
F: Fn(<I as Input>::Item) -> bool,
{
move |i: Input| i.split_at_position_complete(|c| !cond(c))
move |i: I| i.split_at_position_complete(|c| !cond(c))
}

/// Returns the longest (at least 1) input slice that matches the predicate.
Expand All @@ -210,14 +200,12 @@ where
/// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
/// assert_eq!(alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhile1))));
/// ```
pub fn take_while1<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_while1<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
I: Input,
F: Fn(<I as Input>::Item) -> bool,
{
move |i: Input| {
move |i: I| {
let e: ErrorKind = ErrorKind::TakeWhile1;
i.split_at_position1_complete(|c| !cond(c), e)
}
Expand Down Expand Up @@ -246,16 +234,16 @@ where
/// assert_eq!(short_alpha(b"ed"), Err(Err::Error(Error::new(&b"ed"[..], ErrorKind::TakeWhileMN))));
/// assert_eq!(short_alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhileMN))));
/// ```
pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(
pub fn take_while_m_n<F, I, Error: ParseError<I>>(
m: usize,
n: usize,
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
F: Fn(<Input as InputIter>::Item) -> bool,
I: Input + Slice<RangeFrom<usize>>,
F: Fn(<I as Input>::Item) -> bool,
{
move |i: Input| {
move |i: I| {
let input = i;

match input.position(|c| !cond(c)) {
Expand Down Expand Up @@ -328,14 +316,12 @@ where
/// assert_eq!(till_colon(""), Ok(("", "")));
/// ```
#[allow(clippy::redundant_closure)]
pub fn take_till<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_till<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
I: Input,
F: Fn(<I as Input>::Item) -> bool,
{
move |i: Input| i.split_at_position_complete(|c| cond(c))
move |i: I| i.split_at_position_complete(|c| cond(c))
}

/// Returns the longest (at least 1) input slice till a predicate is met.
Expand All @@ -360,14 +346,12 @@ where
/// assert_eq!(till_colon(""), Err(Err::Error(Error::new("", ErrorKind::TakeTill1))));
/// ```
#[allow(clippy::redundant_closure)]
pub fn take_till1<F, Input, Error: ParseError<Input>>(
cond: F,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_till1<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTakeAtPosition,
F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
I: Input,
F: Fn(<I as Input>::Item) -> bool,
{
move |i: Input| {
move |i: I| {
let e: ErrorKind = ErrorKind::TakeTill1;
i.split_at_position1_complete(|c| cond(c), e)
}
Expand Down Expand Up @@ -402,15 +386,13 @@ where
/// assert_eq!(take::<_, _, Error<_>>(1usize)("💙"), Ok(("", "💙")));
/// assert_eq!(take::<_, _, Error<_>>(1usize)("💙".as_bytes()), Ok((b"\x9F\x92\x99".as_ref(), b"\xF0".as_ref())));
/// ```
pub fn take<C, Input, Error: ParseError<Input>>(
count: C,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take<C, I, Error: ParseError<I>>(count: C) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputIter + InputTake,
I: Input,
C: ToUsize,
{
let c = count.to_usize();
move |i: Input| match i.slice_index(c) {
move |i: I| match i.slice_index(c) {
Err(_needed) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Eof))),
Ok(index) => Ok(i.take_split(index)),
}
Expand All @@ -434,14 +416,12 @@ where
/// assert_eq!(until_eof(""), Err(Err::Error(Error::new("", ErrorKind::TakeUntil))));
/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
/// ```
pub fn take_until<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_until<T, I, Error: ParseError<I>>(tag: T) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTake + FindSubstring<T>,
I: Input + FindSubstring<T>,
T: InputLength + Clone,
{
move |i: Input| {
move |i: I| {
let t = tag.clone();
let res: IResult<_, _, Error> = match i.find_substring(t) {
None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
Expand Down Expand Up @@ -470,14 +450,12 @@ where
/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
/// assert_eq!(until_eof("eof"), Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil))));
/// ```
pub fn take_until1<T, Input, Error: ParseError<Input>>(
tag: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
pub fn take_until1<T, I, Error: ParseError<I>>(tag: T) -> impl Fn(I) -> IResult<I, I, Error>
where
Input: InputTake + FindSubstring<T>,
I: Input + FindSubstring<T>,
T: InputLength + Clone,
{
move |i: Input| {
move |i: I| {
let t = tag.clone();
let res: IResult<_, _, Error> = match i.find_substring(t) {
None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
Expand Down Expand Up @@ -508,27 +486,21 @@ where
/// assert_eq!(esc(r#"12\"34;"#), Ok((";", r#"12\"34"#)));
/// ```
///
pub fn escaped<'a, Input: 'a, Error, F, G, O1, O2>(
pub fn escaped<'a, I: 'a, Error, F, G, O1, O2>(
mut normal: F,
control_char: char,
mut escapable: G,
) -> impl FnMut(Input) -> IResult<Input, Input, Error>
) -> impl FnMut(I) -> IResult<I, I, Error>
where
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
<Input as InputIter>::Item: crate::traits::AsChar,
F: Parser<Input, O1, Error>,
G: Parser<Input, O2, Error>,
Error: ParseError<Input>,
I: Clone + crate::traits::Offset + Input + Slice<RangeFrom<usize>>,
<I as Input>::Item: crate::traits::AsChar,
F: Parser<I, O1, Error>,
G: Parser<I, O2, Error>,
Error: ParseError<I>,
{
use crate::traits::AsChar;

move |input: Input| {
move |input: I| {
let mut i = input.clone();

while i.input_len() > 0 {
Expand Down Expand Up @@ -622,30 +594,24 @@ where
/// ```
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
pub fn escaped_transform<I, Error, F, G, O1, O2, ExtendItem, Output>(
mut normal: F,
control_char: char,
mut transform: G,
) -> impl FnMut(Input) -> IResult<Input, Output, Error>
) -> impl FnMut(I) -> IResult<I, Output, Error>
where
Input: Clone
+ crate::traits::Offset
+ InputLength
+ InputTake
+ InputTakeAtPosition
+ Slice<RangeFrom<usize>>
+ InputIter,
Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
I: Clone + crate::traits::Offset + Input + Slice<RangeFrom<usize>>,
I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
<Input as InputIter>::Item: crate::traits::AsChar,
F: Parser<Input, O1, Error>,
G: Parser<Input, O2, Error>,
Error: ParseError<Input>,
<I as Input>::Item: crate::traits::AsChar,
F: Parser<I, O1, Error>,
G: Parser<I, O2, Error>,
Error: ParseError<I>,
{
use crate::traits::AsChar;

move |input: Input| {
move |input: I| {
let mut index = 0;
let mut res = input.new_builder();

Expand Down

0 comments on commit 110261a

Please sign in to comment.