pub trait ParserExt<I, O, E>: Parser<I, O, E> + Sized {
Show 24 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<C>(self, context: C) -> Context<Self, C>
    where
        E: ContextError<I, C>,
        I: Clone,
        C: 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 opt_precedes<F, O2>(self, successor: F) -> OptionalPreceded<Self, F>
    where
        E: ParseError<I>,
        I: Clone,
        F: Parser<I, O2, E>
, { ... } fn opt_preceded_by<F, O2>(self, prefix: F) -> OptionalPreceded<F, Self>
    where
        E: ParseError<I>,
        I: Clone,
        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<I, &'a str, E>,
        I: Clone,
        T: FromStr,
        E: FromExternalError<I, T::Err>
, { ... } fn parse_from_str_cut<'a, T>(self) -> FromStrCutParser<Self, T>
    where
        Self: Parser<I, &'a str, E>,
        I: Clone,
        T: FromStr,
        E: FromExternalError<I, 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 cool_asserts::assert_matches;
use nom::branch::alt;
use nom::character::complete::char;
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::tag::complete::tag;
use nom_supreme::error::{ErrorTree, BaseErrorKind, Expectation};

let mut parser = alt((
    tag("Hello").terminated(char(']')).cut().preceded_by(char('[')),
    tag("World").terminated(char(')')).cut().preceded_by(char('(')),
));

assert_matches!(parser.parse("[Hello]"), Ok(("", "Hello")));
assert_matches!(parser.parse("(World)"), Ok(("", "World")));

let branches = assert_matches!(
    parser.parse("ABC"),
    Err(Err::Error(ErrorTree::Alt(branches))) => branches
);

assert_matches!(
    branches.as_slice(),
    [
        ErrorTree::Base {
            kind: BaseErrorKind::Expected(Expectation::Char('[')),
            location: "ABC",
        },
        ErrorTree::Base {
            kind: BaseErrorKind::Expected(Expectation::Char('(')),
            location: "ABC",
        },
    ]
);

// Notice in this example that there's no error for [Hello]. The cut after
// [ prevented the other branch from being attempted, and prevented earlier
// errors from being retained
assert_matches!(
    parser.parse("(Hello)"),
    Err(Err::Failure(ErrorTree::Base {
        kind: BaseErrorKind::Expected(Expectation::Tag("World")),
        location: "Hello)",
    }))
);

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 cool_asserts::assert_matches;
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 choices = assert_matches!(
    parser.parse("null"),
    Err(Err::Error(ErrorTree::Alt(choices))) => choices
);

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 optionally precede by another one. self will run first, and then the successor will run even if self returns an error. Both outputs will be returned. This is functionally equivalent to self.opt().and(successor), but it has the added benefit that if both parsers return an error, the error from the prefix will be retained, rather than discarded.

use cool_asserts::assert_matches;
use nom::character::complete::{digit1, char};
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::error::{ErrorTree, BaseErrorKind, Expectation};

let mut parser = char('-').or(char('+')).opt_precedes(digit1);

assert_matches!(parser.parse("123"), Ok(("", (None, "123"))));
assert_matches!(parser.parse("-123"), Ok(("", (Some('-'), "123"))));

let choices = assert_matches!(
    parser.parse("abc"),
    Err(Err::Error(ErrorTree::Alt(choices))) => choices,
);

assert_matches!(choices.as_slice(), [
    ErrorTree::Base {
        location: "abc",
        kind: BaseErrorKind::Expected(Expectation::Char('-'))
    },
    ErrorTree::Base {
        location: "abc",
        kind: BaseErrorKind::Expected(Expectation::Char('+'))
    },
    ErrorTree::Base {
        location: "abc",
        kind: BaseErrorKind::Expected(Expectation::Digit)
    },
]);

Make this parser optionally preceded by another one. The prefix will run first, and then this parser will run even if the prefix returned an error. Both outputs will be returned. This is functionally equivalent to prefix.opt().and(self), but it has the added benefit that if both parsers return an error, the error from the prefix will be retained, rather than discarded.

use cool_asserts::assert_matches;
use nom::character::complete::{digit1, char};
use nom_supreme::parser_ext::ParserExt;
use nom_supreme::error::{ErrorTree, BaseErrorKind, Expectation};

let mut parser = digit1.opt_preceded_by(char('-'));

assert_matches!(parser.parse("123"), Ok(("", (None, "123"))));
assert_matches!(parser.parse("-123"), Ok(("", (Some('-'), "123"))));

let choices = assert_matches!(
    parser.parse("abc"),
    Err(Err::Error(ErrorTree::Alt(choices))) => choices,
);

assert_matches!(choices.as_slice(), [
    ErrorTree::Base {
        location: "abc",
        kind: BaseErrorKind::Expected(Expectation::Char('-'))
    },
    ErrorTree::Base {
        location: "abc",
        kind: BaseErrorKind::Expected(Expectation::Digit)
    },
]);

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