Skip to content

Commit

Permalink
remove the parse combinator
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Jan 2, 2023
1 parent 5ac83e5 commit 46a08bf
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 53 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ extern crate nom;
use nom::{
IResult,
bytes::complete::{tag, take_while_m_n},
combinator::{map_res, parse},
combinator::map_res,
Parser,
};

#[derive(Debug,PartialEq)]
Expand All @@ -72,7 +73,7 @@ fn hex_primary(input: &str) -> IResult<&str, u8> {

fn hex_color(input: &str) -> IResult<&str, Color> {
let (input, _) = tag("#")(input)?;
let (input, (red, green, blue)) = parse((hex_primary, hex_primary, hex_primary))(input)?;
let (input, (red, green, blue)) = (hex_primary, hex_primary, hex_primary).parse(input)?;

Ok((input, Color { red, green, blue }))
}
Expand Down
1 change: 0 additions & 1 deletion doc/choosing_a_combinator.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ The following parsers could be found on [docs.rs number section](https://docs.rs
- [`map_res`](https://docs.rs/nom/latest/nom/combinator/fn.map_res.html): Maps a function returning a `Result` on the output of a parser
- [`not`](https://docs.rs/nom/latest/nom/combinator/fn.not.html): Returns a result only if the embedded parser returns `Error` or `Incomplete`. Does not consume the input
- [`opt`](https://docs.rs/nom/latest/nom/combinator/fn.opt.html): Make the underlying parser optional
- [`parse`](https://docs.rs/nom/latest/nom/combinator/fn.parse.html): Make the underlying parser a `FnMut`, so callable in the imperative style.
- [`peek`](https://docs.rs/nom/latest/nom/combinator/fn.peek.html): Returns a result without consuming the input
- [`recognize`](https://docs.rs/nom/latest/nom/combinator/fn.recognize.html): If the child parser was successful, return the consumed input as the produced value
- [`consumed`](https://docs.rs/nom/latest/nom/combinator/fn.consumed.html): If the child parser was successful, return a tuple of the consumed input and the produced output.
Expand Down
4 changes: 2 additions & 2 deletions doc/making_a_new_parser_from_scratch.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ fn request_line(i: &[u8]) -> IResult<&[u8], Request> {
// Tuples of parsers are a parser themselves,
// parsing with each of them sequentially and returning a tuple of their results.
// Unlike most other parsers, parser tuples are not `FnMut`, they must be wrapped
// in the `parse` function to be able to be used in the same way as the others.
// in the `parse` function to be able to be used in the same way as the others.
let (input, (method, _, url, _, version, _)) =
parse((method, space, url, space, http_version, line_ending))(i)?;
(method, space, url, space, http_version, line_ending).parse(i)?;

Ok((input, Request { method, url, version }))
}
Expand Down
21 changes: 0 additions & 21 deletions src/combinator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,6 @@ use crate::traits::{Compare, CompareResult, Offset, Slice};
#[cfg(test)]
mod tests;

/// Transforms a general `Parser` to a `FnMut` parser.
///
/// The purpose of this combinator is to allow calling
/// a `Parser` which is not an `FnMut` in the imperative style.
///
/// ```rust
/// # use nom::character::complete::digit1;
/// # use nom::bytes::complete::tag;
/// # use nom::IResult;
/// # use nom::combinator::parse;
/// fn id_number_parser(input: &str) -> IResult<&str, &str> {
/// let (input, (_, id_number)) = parse((tag("id"), digit1))(input)?;
/// Ok((input, id_number))
/// }
/// ```
pub fn parse<I, O, E: ParseError<I>, P: Parser<I, O, E>>(
mut l: P,
) -> impl FnMut(I) -> IResult<I, O, E> {
move |i: I| l.parse(i)
}

/// Return the remaining input.
///
/// ```rust
Expand Down
24 changes: 14 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
//! ```rust
//! use nom::{
//! IResult,
//! Parser,
//! bytes::complete::{tag, take_while_m_n},
//! combinator::{map_res, parse}};
//! combinator::map_res
//! };
//!
//! #[derive(Debug,PartialEq)]
//! pub struct Color {
Expand All @@ -35,7 +37,7 @@
//!
//! fn hex_color(input: &str) -> IResult<&str, Color> {
//! let (input, _) = tag("#")(input)?;
//! let (input, (red, green, blue)) = parse((hex_primary, hex_primary, hex_primary))(input)?;
//! let (input, (red, green, blue)) = (hex_primary, hex_primary, hex_primary).parse(input)?;
//!
//! Ok((input, Color { red, green, blue }))
//! }
Expand Down Expand Up @@ -259,23 +261,25 @@
//!
//! ```rust
//! # fn main() {
//! use nom::{error::ErrorKind, Needed,
//! number::streaming::be_u16,
//! combinator::parse,
//! bytes::streaming::{tag, take}};
//! use nom::{
//! error::ErrorKind,
//! Needed,
//! Parser,
//! number::streaming::be_u16,
//! bytes::streaming::{tag, take}};
//!
//! let mut tpl = parse((be_u16, take(3u8), tag("fg")));
//! let mut tpl = (be_u16, take(3u8), tag("fg"));
//!
//! assert_eq!(
//! tpl(&b"abcdefgh"[..]),
//! tpl.parse(&b"abcdefgh"[..]),
//! Ok((
//! &b"h"[..],
//! (0x6162u16, &b"cde"[..], &b"fg"[..])
//! ))
//! );
//! assert_eq!(tpl(&b"abcde"[..]), Err(nom::Err::Incomplete(Needed::new(2))));
//! assert_eq!(tpl.parse(&b"abcde"[..]), Err(nom::Err::Incomplete(Needed::new(2))));
//! let input = &b"abcdejk"[..];
//! assert_eq!(tpl(input), Err(nom::Err::Error((&input[5..], ErrorKind::Tag))));
//! assert_eq!(tpl.parse(input), Err(nom::Err::Error((&input[5..], ErrorKind::Tag))));
//! # }
//! ```
//!
Expand Down
6 changes: 6 additions & 0 deletions src/sequence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,14 @@ where
/// Helper trait for the tuple combinator.
///
/// This trait is implemented for tuples of parsers of up to 21 elements.
#[deprecated(since = "8.0.0", note = "`Parser` is directly implemented for tuples")]
#[allow(deprecated)]
pub trait Tuple<I, O, E> {
/// Parses the input and returns a tuple of results of each parser.
fn parse(&mut self, input: I) -> IResult<I, O, E>;
}

#[allow(deprecated)]
impl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output, Error>>
Tuple<Input, (Output,), Error> for (F,)
{
Expand All @@ -218,6 +221,7 @@ macro_rules! tuple_trait(

macro_rules! tuple_trait_impl(
($($name:ident $ty: ident),+) => (
#[allow(deprecated)]
impl<
Input: Clone, $($ty),+ , Error: ParseError<Input>,
$($name: Parser<Input, $ty, Error>),+
Expand Down Expand Up @@ -255,6 +259,7 @@ tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ
// Special case: implement `Tuple` for `()`, the unit type.
// This can come up in macros which accept a variable number of arguments.
// Literally, `()` is an empty tuple, so it should simply parse nothing.
#[allow(deprecated)]
impl<I, E: ParseError<I>> Tuple<I, (), E> for () {
fn parse(&mut self, input: I) -> IResult<I, (), E> {
Ok((input, ()))
Expand All @@ -273,6 +278,7 @@ impl<I, E: ParseError<I>> Tuple<I, (), E> for () {
/// assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
/// ```
#[deprecated(since = "8.0.0", note = "`Parser` is directly implemented for tuples")]
#[allow(deprecated)]
pub fn tuple<I, O, E: ParseError<I>, List: Tuple<I, O, E>>(
mut l: List,
) -> impl FnMut(I) -> IResult<I, O, E> {
Expand Down
13 changes: 8 additions & 5 deletions src/sequence/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ use crate::bytes::streaming::{tag, take};
use crate::error::{Error, ErrorKind};
use crate::internal::{Err, IResult, Needed};
use crate::number::streaming::be_u16;
use crate::combinator::parse;

#[test]
fn single_element_tuples() {
use crate::character::complete::alpha1;
use crate::{error::ErrorKind, Err};

let mut parser = parse((alpha1,));
assert_eq!(parser("abc123def"), Ok(("123def", ("abc",))));
let mut parser = (alpha1,);
assert_eq!(
parser("123def"),
crate::Parser::parse(&mut parser, "abc123def"),
Ok(("123def", ("abc",)))
);
assert_eq!(
crate::Parser::parse(&mut parser, "123def"),
Err(Err::Error(("123def", ErrorKind::Alpha)))
);
}
Expand Down Expand Up @@ -260,7 +262,7 @@ fn delimited_test() {
fn tuple_test() {
#[allow(clippy::type_complexity)]
fn tuple_3(i: &[u8]) -> IResult<&[u8], (u16, &[u8], &[u8])> {
parse((be_u16, take(3u8), tag("fg")))(i)
crate::Parser::parse(&mut (be_u16, take(3u8), tag("fg")), i)
}

assert_eq!(
Expand All @@ -276,6 +278,7 @@ fn tuple_test() {
}

#[test]
#[allow(deprecated)]
fn unit_type() {
assert_eq!(
tuple::<&'static str, (), Error<&'static str>, ()>(())("abxsbsh"),
Expand Down
6 changes: 3 additions & 3 deletions tests/css.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use nom::bytes::complete::{tag, take_while_m_n};
use nom::combinator::{map_res, parse};
use nom::IResult;
use nom::combinator::map_res;
use nom::{IResult, Parser};

#[derive(Debug, Eq, PartialEq)]
pub struct Color {
Expand All @@ -23,7 +23,7 @@ fn hex_primary(input: &str) -> IResult<&str, u8> {

fn hex_color(input: &str) -> IResult<&str, Color> {
let (input, _) = tag("#")(input)?;
let (input, (red, green, blue)) = parse((hex_primary, hex_primary, hex_primary))(input)?;
let (input, (red, green, blue)) = (hex_primary, hex_primary, hex_primary).parse(input)?;

Ok((input, Color { red, green, blue }))
}
Expand Down
6 changes: 3 additions & 3 deletions tests/ini.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use nom::{
character::complete::{
alphanumeric1 as alphanumeric, char, multispace0 as multispace, space0 as space,
},
combinator::{map, map_res, opt, parse},
combinator::{map, map_res, opt},
multi::many0,
sequence::{delimited, pair, separated_pair, terminated},
IResult,
IResult, Parser,
};

use std::collections::HashMap;
Expand All @@ -21,7 +21,7 @@ fn category(i: &[u8]) -> IResult<&[u8], &str> {

fn key_value(i: &[u8]) -> IResult<&[u8], (&str, &str)> {
let (i, key) = map_res(alphanumeric, str::from_utf8)(i)?;
let (i, _) = parse((opt(space), char('='), opt(space)))(i)?;
let (i, _) = (opt(space), char('='), opt(space)).parse(i)?;
let (i, val) = map_res(take_while(|c| c != b'\n' && c != b';'), str::from_utf8)(i)?;
let (i, _) = opt(pair(char(';'), take_while(|c| c != b'\n')))(i)?;
Ok((i, (key, val)))
Expand Down
6 changes: 3 additions & 3 deletions tests/ini_str.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use nom::{
bytes::complete::{is_a, tag, take_till, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, space0 as space},
combinator::{opt, parse},
combinator::opt,
multi::many0,
sequence::{delimited, pair, terminated},
IResult,
IResult, Parser,
};

use std::collections::HashMap;
Expand All @@ -30,7 +30,7 @@ fn category(i: &str) -> IResult<&str, &str> {

fn key_value(i: &str) -> IResult<&str, (&str, &str)> {
let (i, key) = alphanumeric(i)?;
let (i, _) = parse((opt(space), tag("="), opt(space)))(i)?;
let (i, _) = (opt(space), tag("="), opt(space)).parse(i)?;
let (i, val) = take_till(is_line_ending_or_comment)(i)?;
let (i, _) = opt(space)(i)?;
let (i, _) = opt(pair(tag(";"), not_line_ending))(i)?;
Expand Down
5 changes: 2 additions & 3 deletions tests/overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ use nom::bytes::streaming::take;
use nom::multi::{length_data, many0};
#[cfg(feature = "alloc")]
use nom::number::streaming::be_u64;
use nom::combinator::parse;
use nom::{Err, IResult, Needed};
use nom::{Err, IResult, Needed, Parser};

// Parser definition

// We request a length that would trigger an overflow if computing consumed + requested
fn parser02(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
parse((take(1_usize), take(18446744073709551615_usize)))(i)
(take(1_usize), take(18446744073709551615_usize)).parse(i)
}

#[test]
Expand Down

0 comments on commit 46a08bf

Please sign in to comment.