mirror of
https://gitee.com/openharmony/third_party_rust_nom
synced 2024-11-23 15:40:19 +00:00
consumed (previously with_input) parser combinator (#1146)
* consumed parser * Update Add test and modify choosing a combinator
This commit is contained in:
parent
4a30ddc88d
commit
48c5a7cc3f
@ -85,6 +85,7 @@ Parsing integers from binary formats can be done in two ways: With parser functi
|
||||
- `parse_to!`: Uses the parse method from `std::str::FromStr` to convert the current input to the specified type
|
||||
- `peek!`: Returns a result without consuming the input
|
||||
- `recognize!`: If the child parser was successful, return the consumed input as the produced value
|
||||
- `consumed()`: If the child parser was successful, return a tuple of the consumed input and the produced output.
|
||||
- `return_error!`: Prevents backtracking if the child parser fails
|
||||
- `tap!`: Allows access to the parser's result without affecting it
|
||||
- `verify!`: Returns the result of the child parser if it satisfies a verification function
|
||||
|
@ -660,7 +660,76 @@ where
|
||||
recognize(parser)(input)
|
||||
}
|
||||
|
||||
/// Transforms an error to failure.
|
||||
/// if the child parser was successful, return the consumed input with the output
|
||||
/// as a tuple. Functions similarly to [recognize](fn.recognize.html) except it
|
||||
/// returns the parser output as well.
|
||||
///
|
||||
/// This can be useful especially in cases where the output is not the same type
|
||||
/// as the input, or the input is a user defined type.
|
||||
///
|
||||
/// Returned tuple is of the format `(consumed input, produced output)`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use] extern crate nom;
|
||||
/// # use nom::{Err,error::ErrorKind, IResult};
|
||||
/// use nom::combinator::{consumed, value, recognize, map};
|
||||
/// use nom::character::complete::{char, alpha1};
|
||||
/// use nom::bytes::complete::tag;
|
||||
/// use nom::sequence::separated_pair;
|
||||
///
|
||||
/// fn inner_parser(input: &str) -> IResult<&str, bool> {
|
||||
/// value(true, tag("1234"))(input)
|
||||
/// }
|
||||
///
|
||||
/// # fn main() {
|
||||
///
|
||||
/// let mut consumed_parser = consumed(value(true, separated_pair(alpha1, char(','), alpha1)));
|
||||
///
|
||||
/// assert_eq!(consumed_parser("abcd,efgh1"), Ok(("1", ("abcd,efgh", true))));
|
||||
/// assert_eq!(consumed_parser("abcd;"),Err(Err::Error((";", ErrorKind::Char))));
|
||||
///
|
||||
///
|
||||
/// // the first output (representing the consumed input)
|
||||
/// // should be the same as that of the `recognize` parser.
|
||||
/// let mut recognize_parser = recognize(inner_parser);
|
||||
/// let mut consumed_parser = map(consumed(inner_parser), |(consumed, output)| consumed);
|
||||
///
|
||||
/// assert_eq!(recognize_parser("1234"), consumed_parser("1234"));
|
||||
/// assert_eq!(recognize_parser("abcd"), consumed_parser("abcd"));
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn consumed<I, O, F, E>(mut parser: F) -> impl FnMut(I) -> IResult<I, (I, O), E>
|
||||
where
|
||||
I: Clone + Offset + Slice<RangeTo<usize>>,
|
||||
E: ParseError<I>,
|
||||
F: Parser<I, O, E>
|
||||
{
|
||||
move |input: I| {
|
||||
let i = input.clone();
|
||||
match parser.parse(i) {
|
||||
Ok((remaining, result )) => {
|
||||
let index = input.offset(&remaining);
|
||||
let consumed = input.slice(..index);
|
||||
Ok((remaining, (consumed, result)))
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn consumedc<I, O, E: ParseError<I>, F>(
|
||||
input: I,
|
||||
parser: F
|
||||
) -> IResult<I, (I, O), E>
|
||||
where
|
||||
I: Clone + Offset + Slice<RangeTo<usize>>,
|
||||
E: ParseError<E>,
|
||||
F: Fn(I) -> IResult<I, O, E>
|
||||
{ consumed(parser)(input) }
|
||||
|
||||
|
||||
/// transforms an error to failure
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use] extern crate nom;
|
||||
|
Loading…
Reference in New Issue
Block a user