Trait nom_supreme::parser_ext::ParserExt[][src]

pub trait ParserExt<I, O, E>: Parser<I, O, E> + Sized {
Show 22 methods fn by_ref(&mut self) -> RefParser<'_, Self> { ... }
fn all_consuming(self) -> AllConsuming<Self>
    where
        I: InputLength,
        E: ParseError<I>
, { ... }
fn complete(self) -> Complete<Self>
    where
        I: Clone,
        E: ParseError<I>
, { ... }
fn cut(self) -> Cut<Self> { ... }
fn map_res<F, O2, E2>(self, func: F) -> MapRes<Self, F, O, E2>
    where
        F: FnMut(O) -> Result<O2, E2>,
        E: FromExternalError<I, E2>,
        I: Clone
, { ... }
fn map_res_cut<F, O2, E2>(self, func: F) -> MapResCut<Self, F, O, E2>
    where
        F: FnMut(O) -> Result<O2, E2>,
        E: FromExternalError<I, E2>,
        I: Clone
, { ... }
fn opt(self) -> Optional<Self>
    where
        I: Clone
, { ... }
fn recognize(self) -> Recognize<Self, O>
    where
        I: Clone + Slice<RangeTo<usize>> + Offset
, { ... }
fn with_recognized(self) -> WithRecognized<Self>
    where
        I: Clone + Slice<RangeTo<usize>> + Offset
, { ... }
fn value<T: Clone>(self, value: T) -> Value<T, Self, O> { ... }
fn verify<F>(self, verifier: F) -> Verify<Self, F>
    where
        F: Fn(&O) -> bool,
        I: Clone,
        E: ParseError<I>
, { ... }
fn context(self, context: &'static str) -> Context<Self>
    where
        E: ContextError<I>,
        I: Clone
, { ... }
fn terminated<F, O2>(self, terminator: F) -> Terminated<Self, F, O2>
    where
        F: Parser<I, O2, E>
, { ... }
fn precedes<F, O2>(self, successor: F) -> Preceded<F, Self, O>
    where
        F: Parser<I, O2, E>
, { ... }
fn preceded_by<F, O2>(self, prefix: F) -> Preceded<Self, F, O2>
    where
        F: Parser<I, O2, E>
, { ... }
fn delimited_by<D, O2>(self, delimiter: D) -> Delimited<Self, D, O2>
    where
        D: Parser<I, O2, E>
, { ... }
fn peek(self) -> Peek<Self>
    where
        I: Clone
, { ... }
fn not(self) -> Not<Self, O>
    where
        I: Clone,
        E: ParseError<I>
, { ... }
fn parse_from_str<'a, T>(self) -> FromStrParser<Self, T>
    where
        Self: Parser<&'a str, &'a str, E>,
        T: FromStr,
        E: FromExternalError<&'a str, T::Err>
, { ... }
fn parse_from_str_cut<'a, T>(self) -> FromStrCutParser<Self, T>
    where
        Self: Parser<&'a str, &'a str, E>,
        T: FromStr,
        E: FromExternalError<&'a str, T::Err>
, { ... }
fn array(self) -> ArrayParser<Self> { ... }
fn separated_array<F, O2>(
        self,
        separator: F
    ) -> SeparatedArrayParser<Self, F, O2>
    where
        F: Parser<I, O2, E>
, { ... }
}
Expand description

Additional postfix parser combinators, as a complement to Parser. Mostly these are postfix versions of the combinators in nom::combinator and nom::sequence, with some additional combinators original to nom-supreme.

Compatibility note: it is expected that eventually many of these postfix methods will eventually be added directly to the Parser trait. It will therefore not be considered a compatibility break to remove those methods from ParserExt, if they have the same name and signature.

Provided methods

Borrow a parser. This allows building parser combinators while still retaining ownership of the original parser. This is necessary because impl<T: Parser> Parser for &mut T is impossible due to conflicts with impl<T: FnMut> Parser for T.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello");

let mut subparser = parser.by_ref().terminated(tag(", World"));

assert_eq!(subparser.parse("Hello, World!"), Ok(("!", "Hello")));
assert_eq!(
    subparser.parse("Hello"),
    Err(Err::Error(Error{input: "", code: ErrorKind::Tag}))
);

// We still have ownership of the original parser

assert_eq!(parser.parse("Hello, World!"), Ok((", World!", "Hello")));
assert_eq!(parser.parse("Hello"), Ok(("", "Hello")));

Create a parser that must consume all of the input, or else return an error.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").all_consuming();

assert_eq!(parser.parse("Hello"), Ok(("", "Hello")));
assert_eq!(
    parser.parse("World"),
    Err(Err::Error(Error{input: "World", code: ErrorKind::Tag}))
);
assert_eq!(
    parser.parse("Hello World"),
    Err(Err::Error(Error{input: " World", code: ErrorKind::Eof}))
);

Create a parser that transforms Incomplete into Error.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::streaming::tag;

let mut parser = tag("Hello").complete();

assert_eq!(parser.parse("Hello"), Ok(("", "Hello")));
assert_eq!(
    parser.parse("World"),
    Err(Err::Error(Error{input: "World", code: ErrorKind::Tag}))
);
assert_eq!(
    parser.parse("Hel"),
    Err(Err::Error(Error{input: "Hel", code: ErrorKind::Complete}))
);

Create a parser that transforms Error into Failure. This will end the parse immediately, even if there are other branches that could occur.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").cut();

assert_eq!(parser.parse("Hello"), Ok(("", "Hello")));
assert_eq!(
    parser.parse("World"),
    Err(Err::Failure(Error{input: "World", code: ErrorKind::Tag}))
);

Create a parser that applies a mapping function func to the output of the subparser. Any errors from func will be transformed into parse errors via FromExternalError.

Example

use nom::character::complete::alphanumeric1;
use nom_supreme::parser_ext::ParserExt;

let mut parser = alphanumeric1.map_res(|s: &str| s.parse());

assert_eq!(parser.parse("10 abc"), Ok((" abc", 10)));
assert_eq!(
    parser.parse("<===>"),
    Err(Err::Error(Error{input: "<===>", code: ErrorKind::AlphaNumeric})),
);
assert_eq!(
    parser.parse("abc abc"),
    Err(Err::Error(Error{input: "abc abc", code: ErrorKind::MapRes})),
);

Create a parser that applies a mapping function func to the output of the subparser. Any errors from func will be transformed into parse failures via FromExternalError. This will end the parse immediately, even if there are other branches that could occur.

Example

use nom::character::complete::alphanumeric1;
use nom_supreme::parser_ext::ParserExt;

let mut parser = alphanumeric1.map_res_cut(|s: &str| s.parse());

assert_eq!(parser.parse("10 abc"), Ok((" abc", 10)));
assert_eq!(
    parser.parse("<===>"),
    Err(Err::Error(Error{input: "<===>", code: ErrorKind::AlphaNumeric})),
);
assert_eq!(
    parser.parse("abc abc"),
    Err(Err::Failure(Error{input: "abc abc", code: ErrorKind::MapRes})),
);

Make this parser optional; if it fails to parse, instead it returns None with the input in the original position.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

fn parser(input: &str) -> IResult<&str, Option<&str>> {
    tag("Hello").opt().parse(input)
}

assert_eq!(parser.parse("Hello, World"), Ok((", World", Some("Hello"))));
assert_eq!(parser.parse("World"), Ok(("World", None)));

let mut parser = tag("Hello").cut().opt();
assert_eq!(
    parser.parse("World"),
    Err(Err::Failure(Error{input: "World", code: ErrorKind::Tag}))
)

Replace this parser’s output with the entire input that was consumed by the parser.

Example

use nom::character::complete::space1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").delimited_by(space1).recognize();

assert_eq!(parser.parse("   Hello   World!"), Ok(("World!", "   Hello   ")));
assert_eq!(
    parser.parse("Hello"),
    Err(Err::Error(Error{input: "Hello", code: ErrorKind::Space}))
)

Return the parsed value, but also return the entire input that was consumed by the parse

Example

use nom::character::complete::space1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").delimited_by(space1).with_recognized();

assert_eq!(parser.parse("   Hello   World!"), Ok(("World!", ("   Hello   ", "Hello"))));
assert_eq!(
    parser.parse("Hello"),
    Err(Err::Error(Error{input: "Hello", code: ErrorKind::Space}))
)

Replace this parser’s output with a clone of value every time it finishes successfully.

Example

use nom::branch::alt;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;
use nom_supreme::error::{ErrorTree, BaseErrorKind, Expectation};


let mut parser = alt((
    tag("true").value(true),
    tag("false").value(false),
));

assert_eq!(parser.parse("true abc").unwrap(), (" abc", true));
assert_eq!(parser.parse("false abc").unwrap(), (" abc", false));

// ErrorTree gives much better error reports for alt and tag.
let err = parser.parse("null").unwrap_err();
let choices = match err {
    Err::Error(ErrorTree::Alt(choices)) => choices,
    _ => panic!("Unexpected error {:?}", err)
};
assert!(matches!(
    choices.as_slice(),
    [
        ErrorTree::Base {
            kind: BaseErrorKind::Expected(Expectation::Tag("true")),
            location: "null",
        },
        ErrorTree::Base {
            kind: BaseErrorKind::Expected(Expectation::Tag("false")),
            location: "null",
        },
    ]
))

Require the output of this parser to pass a verifier function, or else return a parse error.

use nom::character::complete::alpha1;
use nom_supreme::parser_ext::ParserExt;

let mut parser = alpha1.verify(|s: &&str| s.len() == 5);

assert_eq!(parser.parse("Hello"), Ok(("", "Hello")));
assert_eq!(parser.parse("Hello, World"), Ok((", World", "Hello")));
assert_eq!(
    parser.parse("abc"),
    Err(Err::Error(Error{input: "abc", code: ErrorKind::Verify}))
);
assert_eq!(
    parser.parse("abcabcabc"),
    Err(Err::Error(Error{input: "abcabcabc", code: ErrorKind::Verify}))
);
assert_eq!(
    parser.parse("123"),
    Err(Err::Error(Error{input: "123", code: ErrorKind::Alpha}))
);

Add some context to the parser. This context will be added to any errors that are returned from the parser via ContextError.

Example

use nom::sequence::separated_pair;
use nom::character::complete::space1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = separated_pair(
    tag("Hello").context("hello"),
    space1,
    tag("World").context("world"),
)
.context("hello world");

assert_eq!(parser.parse("Hello World"), Ok(("", ("Hello", "World"))));
assert_eq!(
    parser.parse("Hel"),
    Err(Err::Error(VerboseError {errors: vec![
        ("Hel", VerboseErrorKind::Nom(ErrorKind::Tag)),
        ("Hel", VerboseErrorKind::Context("hello")),
        ("Hel", VerboseErrorKind::Context("hello world")),
    ]}))
);
assert_eq!(
    parser.parse("Hello"),
    Err(Err::Error(VerboseError {errors: vec![
        ("", VerboseErrorKind::Nom(ErrorKind::Space)),
        ("Hello", VerboseErrorKind::Context("hello world")),
    ]}))
);
assert_eq!(
    parser.parse("Hello Wor"),
    Err(Err::Error(VerboseError {errors: vec![
        ("Wor", VerboseErrorKind::Nom(ErrorKind::Tag)),
        ("Wor", VerboseErrorKind::Context("world")),
        ("Hello Wor", VerboseErrorKind::Context("hello world")),
    ]}))
);

Add a terminator parser. The terminator will run after this parser, returning any errors, but its output will otherwise be discarded.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").terminated(tag(" World"));

assert_eq!(parser.parse("Hello World!"), Ok(("!", "Hello")));
assert_eq!(
    parser.parse("Hello"),
    Err(Err::Error(Error{input: "", code: ErrorKind::Tag}))
);

Make this parser precede another one. The successor parser will run after this one succeeds, and the successor’s output will be returned.

Example

use nom::character::complete::digit1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Value: ").precedes(digit1);

assert_eq!(parser.parse("Value: 25;"), Ok((";", "25")));
assert_eq!(
    parser.parse("Value: "),
    Err(Err::Error(Error{input: "", code: ErrorKind::Digit}))
);
assert_eq!(
    parser.parse("25"),
    Err(Err::Error(Error{input: "25", code: ErrorKind::Tag}))
);

Make this parser preceded by another one. The prefix will run first, and if it succeeds, its output will be discard and this parser will be run.

Example

use nom::character::complete::digit1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = digit1.preceded_by(tag("Value: "));

assert_eq!(parser.parse("Value: 25;"), Ok((";", "25")));
assert_eq!(
    parser.parse("Value: "),
    Err(Err::Error(Error{input: "", code: ErrorKind::Digit}))
);
assert_eq!(
    parser.parse("25"),
    Err(Err::Error(Error{input: "25", code: ErrorKind::Tag}))
);

Make this parser delimited, requiring a delimiter as both a prefix and a suffix. The output of the delimiters is discarded.

Example

use nom::character::complete::{char, digit1};
use nom_supreme::parser_ext::ParserExt;

let mut parser = digit1.delimited_by(char('\''));

assert_eq!(parser.parse("'123' '456'"), Ok((" '456'", "123")));
assert_eq!(
    parser.parse("'' ''"),
    Err(Err::Error(Error{input: "' ''", code: ErrorKind::Digit}))
);
assert_eq!(
    parser.parse("'123 '"),
    Err(Err::Error(Error{input: " '", code: ErrorKind::Char}))
);

Make this parser peeking: it runs normally but consumes no input.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").peek();

assert_eq!(parser.parse("Hello World"), Ok(("Hello World", "Hello")));
assert_eq!(
    parser.parse("World"),
    Err(Err::Error(Error{input: "World", code: ErrorKind::Tag}))
);

Make this parser a negative lookahead: it will succeed if the subparser fails, and fail if the subparser succeeds.

Example

use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = tag("Hello").not();

assert_eq!(parser.parse("World"), Ok(("World", ())));
assert_eq!(
    parser.parse("Hello World"),
    Err(Err::Error(Error{input: "Hello World", code: ErrorKind::Not})),
);

Create a parser that parses something via FromStr, using this parser as a recognizer for the string to pass to from_str.

Example

use nom::character::complete::digit1;
use nom_supreme::parser_ext::ParserExt;

let mut parser = digit1.parse_from_str();

assert_eq!(parser.parse("123 abc"), Ok((" abc", 123)));
assert_eq!(
    parser.parse("abc"),
    Err(Err::Error(Error{input: "abc", code: ErrorKind::Digit})),
);

Parse error example

If the FromStr parser fails, the error is recoverable from via FromExternalError. In general, though, it’s better practice to ensure your recognizer won’t allow invalid strings to be forwarded to the FromStr parser

use std::num::ParseIntError;
use cool_asserts::assert_matches;
use nom::character::complete::alphanumeric1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::error::{ErrorTree, BaseErrorKind};

let mut parser = alphanumeric1.parse_from_str();

assert_matches!(parser.parse("123 abc"), Ok((" abc", 123)));
assert_matches!(
    parser.parse("abc"),
    Err(Err::Error(ErrorTree::Base{
        location: "abc",
        kind: BaseErrorKind::External(err),
    })) => {
        let _err: &ParseIntError = err.downcast_ref().unwrap();
    },
);

Create a parser that parses something via FromStr, using this parser as a recognizer for the string to pass to from_str. This parser transforms any errors from FromStr into Err::Failure, which will end the overall parse immediately, even if there are other branches that could be tried.

Example

use nom::character::complete::alphanumeric1;
use nom_supreme::parser_ext::ParserExt;

let mut parser = alphanumeric1.parse_from_str_cut();

assert_eq!(parser.parse("123 abc"), Ok((" abc", 123)));
assert_eq!(
    parser.parse("<===>"),
    Err(Err::Error(Error{input: "<===>", code: ErrorKind::AlphaNumeric})),
);
assert_eq!(
    parser.parse("abc"),
    Err(Err::Failure(Error{input: "abc", code: ErrorKind::MapRes})),
);

Parse error example

If the FromStr parser fails, the error is recoverable from via FromExternalError. In general, though, it’s better practice to ensure your recognizer won’t allow invalid strings to be forwarded to the FromStr parser

use std::num::ParseIntError;
use cool_asserts::assert_matches;
use nom::character::complete::alphanumeric1;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::error::{ErrorTree, BaseErrorKind};

let mut parser = alphanumeric1.parse_from_str_cut();

assert_matches!(parser.parse("123 abc"), Ok((" abc", 123)));
assert_matches!(
    parser.parse("abc"),
    Err(Err::Failure(ErrorTree::Base{
        location: "abc",
        kind: BaseErrorKind::External(err),
    })) => {
        let _err: &ParseIntError = err.downcast_ref().unwrap();
    },
);

Create a parser that parses a fixed-size array by running this parser in a loop.

The returned parser implements Parser generically over any const N: usize, which means it can be used to parse arrays of any length

Example

use cool_asserts::assert_matches;
use nom::character::complete::digit1;
use nom_supreme::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = digit1
    .terminated(tag(", "))
    .parse_from_str()
    .array();

assert_matches!(parser.parse("123, 456, 789, abc"), Ok(("789, abc", [123, 456])));
assert_matches!(parser.parse("123, 456, 789, abc"), Ok(("abc", [123, 456, 789])));

let res: Result<(&str, [u16; 4]), Err<Error<&str>>> = parser.parse("123, 456, 789, abc");
assert_matches!(
    res,
    Err(Err::Error(Error{input: "abc", code: ErrorKind::Digit}))
);

Note that this parser does not attach any additional context to the error in the event of a parser; consider using context on the item parser or array parser to add additional information about where in the input there was a parse failure.

Create a parser that parses a fixed-size array by running this parser in a loop, parsing a separator in between each element.

The returned parser implements Parser generically over any const N: usize, which means it can be used to parse arrays of any length

Example

use std::net::{Ipv4Addr, SocketAddrV4};
use cool_asserts::assert_matches;
use nom::character::complete::{char, digit1};
use nom_supreme::ParserExt;
use nom_supreme::tag::complete::tag;

let mut parser = digit1
    .parse_from_str()
    .separated_array(char('.'))
    .map(Ipv4Addr::from)
    .terminated(char(':'))
    .and(digit1.parse_from_str())
    .map(|(ip, port)| SocketAddrV4::new(ip, port));

let (_tail, socket_addr) = parser.parse("192.168.0.1:80").unwrap();
assert_eq!(socket_addr.ip().octets(), [192, 168, 0, 1]);
assert_eq!(socket_addr.port(), 80);

assert_matches!(
    parser.parse("192.168.0.abc:80"),
    Err(Err::Error(Error{input: "abc:80", code: ErrorKind::Digit})),
);

assert_matches!(
    parser.parse("192.168.0.1"),
    Err(Err::Error(Error{input: "", code: ErrorKind::Char})),
);

assert_matches!(
    parser.parse("192.168.0.1000:80"),
    Err(Err::Error(Error{input: "1000:80", code: ErrorKind::MapRes})),
);

assert_matches!(
    parser.parse("192.168.10abc"),
    Err(Err::Error(Error{input: "abc", code: ErrorKind::Char})),
);

Note that this parser does not attach any additional context to the error in the event of a parser; consider using context on the item, separator, or array parsers to add additional information about where in the input there was a parse failure.

Implementors