Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Pass Extra Arguments To Child Parsers In Rust's nom

This is how I'm passing supplemental arguments/parameters to nom parsers inside other parsers (e.g. inside `many1``). The key is on lines 21-22 between the comments. More notes below the code.

Code

//! ```cargo
//! [dependencies]
//! nom = "7.1.3"
//! ```

use nom::bytes::complete::tag;
use nom::error::ParseError;
use nom::multi::many1;
use nom::IResult;
use nom::{ Compare, InputLength, InputTake };

fn main() {
  let left = Ok((" bravo", vec!["alfa"]));
  let right = parse("alfa bravo");
  assert_eq!(left, right);
  println!("test past");
}

fn parse(source: &str) -> IResult<&str, Vec<&str>> {
  let extra_arg = "alfa";

  /////////////////////////////////////////////
  // let (source, result) = many1(|src| 
  // grabber(src, extra_arg))(source)?; 
  // TODO: Write up this version above ^ too//
  /////////////////////////////////////////////
  let (source, result) = many1(grabber(extra_arg))(source)?; 
  /////////////////////////////////////////////

  Ok((source, result))
}

fn grabber<T, Input, Error: ParseError<Input>>(
    extra: T,
) -> impl Fn(Input) -> IResult<Input, Input, Error>
where
    Input: InputTake + Compare<T>,
    T: InputLength + Clone,
{
    tag(extra)
}

//fn grabber<'a>(source: &'a str, extra: &'a str) -> 
 // IResult<&'a str, &'a str> {
  //  let (source, result) = tag(extra)(source)?;
   // Ok((source, result))
//}

Results

test past

Code

alt ((
        |src| block_section_name(src, config),
        |src| block_section_name(src, config),
    ))(source)
  • Get other examples of parsers this works with besides `many1``. Look at `alt``, `opt``, `tuple``, `pair``, etc...)