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.

Use A .map With A nom tag In Rust

This works

Code

//! ```cargo
//! [package]
//! edition = "2021"
//! [dependencies]
//! nom = { version = "7.1.3" }
//! ```


#![allow(unused_imports)]
use nom::bytes::complete::tag;
use nom::IResult;
use nom::Parser;

fn main() {
    assert_eq!(do_example("focus"), Ok(("", "asdf")));
    println!("Done.");
}

fn do_example(source: &str) -> IResult<&str, &str> {
    let (source, attr) = tag("focus")
         .parse(source)
         .map(|(x, _)| (x, "asdf"))?;
    Ok((source, attr))
}

Results

Done.

as opposed to this, which doesn't (and results in a `call expression requires function`` error.

Code

pub fn attr_autofocus(source: &str) -> IResult<&str, Attribute> {
    let (source, attr) =
        tag("autofocus").map(|(x, y)| (x, Attribute::Autofocus))(source)?;
    Ok((source, attr))
}

Here's a look at the full error that I hit when trying to figure this out.

Compiling example_code v0.1.0 (/Users/alan/workshop/rust-playground.alanwsmith.com/site/example_code)
error[E0277]: the trait bound `(&[u8], usize): InputTake` is not satisfied
   --> src/nom_parse_test_v17.rs:513:9
    |
513 |         tag("autofocus").map(|(x, y)| (x, Attribute::Autofocus))(source)?;
    |         ^^^ the trait `InputTake` is not implemented for `(&[u8], usize)`
    |
    = help: the following other types implement trait `InputTake`:
              &'a [u8]
              &'a str
note: required by a bound in `nom::bytes::complete::tag`
   --> /Users/alan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/bytes/complete.rs:36:10
    |
36  |   Input: InputTake + Compare<T>,
    |          ^^^^^^^^^ required by this bound in `tag`

error[E0271]: type mismatch resolving `<&str as InputIter>::Item == u8`
   --> src/nom_parse_test_v17.rs:513:9
    |
513 |         tag("autofocus").map(|(x, y)| (x, Attribute::Autofocus))(source)?;
    |         ^^^ expected `u8`, found `char`
    |
    = note: required for `(&[u8], usize)` to implement `Compare<&str>`
note: required by a bound in `nom::bytes::complete::tag`
   --> /Users/alan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/bytes/complete.rs:36:22
    |
36  |   Input: InputTake + Compare<T>,
    |                      ^^^^^^^^^^ required by this bound in `tag`

error[E0277]: the trait bound `(&[u8], usize): InputIter` is not satisfied
   --> src/nom_parse_test_v17.rs:513:9
    |
513 |         tag("autofocus").map(|(x, y)| (x, Attribute::Autofocus))(source)?;
    |         ^^^ the trait `InputIter` is not implemented for `(&[u8], usize)`
    |
    = help: the following other types implement trait `InputIter`:
              &'a [u8; 0]
              &'a [u8; 10]
              &'a [u8; 11]
              &'a [u8; 12]
              &'a [u8; 13]
              &'a [u8; 14]
              &'a [u8; 15]
              &'a [u8; 16]
            and 27 others
    = note: required for `(&[u8], usize)` to implement `Compare<&str>`
note: required by a bound in `nom::bytes::complete::tag`
   --> /Users/alan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/bytes/complete.rs:36:22
    |
36  |   Input: InputTake + Compare<T>,
    |                      ^^^^^^^^^^ required by this bound in `tag`

error[E0277]: the trait bound `(&[u8], usize): UnspecializedInput` is not satisfied
   --> src/nom_parse_test_v17.rs:513:9
    |
513 |         tag("autofocus").map(|(x, y)| (x, Attribute::Autofocus))(source)?;
    |         ^^^ the trait `UnspecializedInput` is not implemented for `(&[u8], usize)`
    |
    = help: the following other types implement trait `Compare<T>`:
              <&'a [u8] as Compare<&'b [u8; 0]>>
              <&'a [u8] as Compare<&'b [u8; 10]>>
              <&'a [u8] as Compare<&'b [u8; 11]>>
              <&'a [u8] as Compare<&'b [u8; 12]>>
              <&'a [u8] as Compare<&'b [u8; 13]>>
              <&'a [u8] as Compare<&'b [u8; 14]>>
              <&'a [u8] as Compare<&'b [u8; 15]>>
              <&'a [u8] as Compare<&'b [u8; 16]>>
            and 62 others
    = note: required for `(&[u8], usize)` to implement `Compare<&str>`
note: required by a bound in `nom::bytes::complete::tag`
   --> /Users/alan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/bytes/complete.rs:36:22
    |
36  |   Input: InputTake + Compare<T>,
    |                      ^^^^^^^^^^ required by this bound in `tag`

error[E0618]: expected function, found `nom::Map<impl Fn((&[u8], usize)) -> Result<((&[u8], usize), (&[u8], usize)), nom::Err<_>>, [closure@src/nom_parse_test_v17.rs:513:30: 513:38], (&[u8], usize)>`
   --> src/nom_parse_test_v17.rs:513:9
    |
513 |         tag("autofocus").map(|(x, y)| (x, Attribute::Autofocus))(source)?;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------
    |         |
    |         call expression requires function

Some errors have detailed explanations: E0271, E0277, E0618.
For more information about an error, try `rustc --explain E0271`.
error: could not compile `example_code` (lib test) due to 5 previous errors
[Finished running. Exit status: 101]