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")));
fn all_consuming(self) -> AllConsuming<Self> where
I: InputLength,
E: ParseError<I>,
fn all_consuming(self) -> AllConsuming<Self> where
I: InputLength,
E: ParseError<I>,
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})) );
fn complete(self) -> Complete<Self> where
I: Clone,
E: ParseError<I>,
fn complete(self) -> Complete<Self> where
I: Clone,
E: ParseError<I>,
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})), );
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 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,
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})) )
fn with_recognized(self) -> WithRecognized<Self> where
I: Clone + Slice<RangeTo<usize>> + Offset,
fn with_recognized(self) -> WithRecognized<Self> where
I: Clone + Slice<RangeTo<usize>> + Offset,
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")), ]})) );
fn terminated<F, O2>(self, terminator: F) -> Terminated<Self, F, O2> where
F: Parser<I, O2, E>,
fn terminated<F, O2>(self, terminator: F) -> Terminated<Self, F, O2> where
F: Parser<I, O2, E>,
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})) );
fn preceded_by<F, O2>(self, prefix: F) -> Preceded<Self, F, O2> where
F: Parser<I, O2, E>,
fn preceded_by<F, O2>(self, prefix: F) -> Preceded<Self, F, O2> where
F: Parser<I, O2, E>,
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})) );
fn delimited_by<D, O2>(self, delimiter: D) -> Delimited<Self, D, O2> where
D: Parser<I, O2, E>,
fn delimited_by<D, O2>(self, delimiter: D) -> Delimited<Self, D, O2> where
D: Parser<I, O2, E>,
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})) );
fn not(self) -> Not<Self, O> where
I: Clone,
E: ParseError<I>,
fn not(self) -> Not<Self, O> where
I: Clone,
E: ParseError<I>,
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})), );
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<'a, T>(self) -> FromStrParser<Self, T> where
Self: Parser<&'a str, &'a str, E>,
T: FromStr,
E: FromExternalError<&'a str, T::Err>,
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(); }, );
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 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>,
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(); }, );
fn array(self) -> ArrayParser<Self>
fn array(self) -> ArrayParser<Self>
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.
fn separated_array<F, O2>(
self,
separator: F
) -> SeparatedArrayParser<Self, F, O2> where
F: Parser<I, O2, E>,
fn separated_array<F, O2>(
self,
separator: F
) -> SeparatedArrayParser<Self, F, O2> where
F: Parser<I, O2, E>,
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.