1 unstable release

0.1.1 Jul 29, 2019

#198 in #nom


Used in nom-both

MIT/Apache

5KB
72 lines

nom-both

Extension of nom to provide special both_ parsers.

Build Status Crates.io Docs.rs

Requirement

nom must be 5.0.0 or later. nom-both can be applied to function-style parser only.

Usage

[dependencies]
nom-both = "0.1.1"

Example

nom-both provide both_opt and both_alt parser. both_opt means that the parser tries both argument parser and skip. both_alt means that the parser tries both 1st argument parser and 2nd argument parser.

use nom::branch::*;
use nom::bytes::complete::*;
use nom::IResult;
use nom_both::both_parser;

#[both_parser]
pub fn both_opt_parser(s: &str) -> IResult<&str, Option<&str>> {
    let (s, _) = tag("1")(s)?;
    let (s, x) = both_opt(tag("2"))(s)?;
    let (s, _) = tag("2")(s)?;
    let (s, _) = tag("3")(s)?;
    Ok((s, x))
}

#[both_parser]
pub fn both_alt_parser(s: &str) -> IResult<&str, &str> {
    let (s, _) = tag("1")(s)?;
    let (s, x) = both_alt(tag("22"), tag("2"))(s)?;
    let (s, _) = tag("2")(s)?;
    let (s, _) = tag("3")(s)?;
    Ok((s, x))
}

#[test]
fn test() {
    let ret = both_opt_parser("123");
    assert_eq!("None", format!("{:?}", ret.unwrap().1));

    let ret = both_alt_parser("1223");
    assert_eq!("\"2\"", format!("{:?}", ret.unwrap().1));
}

both_opt_parser is expanded as below:

pub fn both_opt_parser(s: &str) -> IResult<&str, Option<&str>> {
    alt((
        { |s| {
            let (s, _) = tag("1")(s)?;
            let (s, x) = nom_both::some(tag("2"))(s)?;
            let (s, _) = tag("2")(s)?;
            let (s, _) = tag("3")(s)?;
            Ok((s, x))
        } },
        { |s| {
            let (s, _) = tag("1")(s)?;
            let (s, x) = nom_both::none(tag("2"))(s)?;
            let (s, _) = tag("2")(s)?;
            let (s, _) = tag("3")(s)?;
            Ok((s, x))
        } },
    ))(s)
}

both_alt_parser is expanded as below:

pub fn both_opt_parser(s: &str) -> IResult<&str, Option<&str>> {
    alt((
        { |s| {
            let (s, _) = tag("1")(s)?;
            let (s, x) = nom_both::alt_left(tag("22"), tag("2"))(s)?;
            let (s, _) = tag("2")(s)?;
            let (s, _) = tag("3")(s)?;
            Ok((s, x))
        } },
        { |s| {
            let (s, _) = tag("1")(s)?;
            let (s, x) = nom_both::alt_right(tag("22"), tag("2"))(s)?;
            let (s, _) = tag("2")(s)?;
            let (s, _) = tag("3")(s)?;
            Ok((s, x))
        } },
    ))(s)
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~2MB
~46K SLoC