title: Rust + nom: how to wrap a parser to emit a token?
body: <p>So I'm trying to port a parser written in Javascript with <a href="https://github.com/jneen/parsimmon" rel="nofollow noreferrer">parsimmon</a>. In the parser I feed a string source input and get tokens. A token is simply an object with a type and a pair of offset values to mark its location in the source:</p>
  <pre class="lang-rust prettyprint-override"><code>enum TokenType {
      Foo,
      Bar
  }
  
  struct Token {
      token_type: TokenType,
      start_offset: usize,
      end_offset: usize,
  }
  </code></pre>
  <p>Then in parsimmon there is a convenient <a href="https://github.com/jneen/parsimmon/blob/master/API.md#parsernodename" rel="nofollow noreferrer">node</a> operator which wraps a parser or a combinator, and make its output a node just like the <code>Token</code> struct described above. I'd like to recreate this behavior with nom, here is what I've got:</p>
  <pre class="lang-rust prettyprint-override"><code>struct LexInput&lt;'a&gt; {
      source: &amp;'a str,
      location: usize,
  }
  
  fn token&lt;'a&gt;(
      parser: impl Fn(&amp;str) -&gt; IResult&lt;&amp;'a str, &amp;str&gt;,
      token_type: TokenType,
  ) -&gt; impl Fn(&amp;LexInput) -&gt; IResult&lt;LexInput&lt;'a&gt;, Token&gt; {
      move |input: &amp;LexInput| {
          let start_offset = input.location;
          let (remaining_source, output) = parser(input.source)?;
          let end_offset = start_offset + output.len();
          let token = Token::new(token_type, start_offset, end_offset);
          let remaining = LexInput::new(remaining_source, end_offset);
  
          Ok((remaining, token))
      }
  }
  </code></pre>
  <p>I'm still quite new to rust so it took me a while to get here, but the code looks promising, except that I don't know how to use it. Instinctively I wrote:</p>
  <pre class="lang-rust prettyprint-override"><code>let (remaining, token) = token(tag(&quot;|&quot;), TokenType::Bar)(&amp;LexInput::new(&quot;|foo&quot;, 0)).unwrap();
  assert_eq!(remaining.source, &quot;foo&quot;);
  </code></pre>
  <p>But of course that does not work. The error message is confusing as usual:</p>
  <pre><code>expected associated type `&lt;impl Fn(&amp;str)-&gt; Result&lt;(&amp;str, &amp;str), nom::Err&lt;nom::error::Error&lt;&amp;str&gt;&gt;&gt; as FnOnce&lt;(&amp;str,)&gt;&gt;::Output`
     found associated type `&lt;impl Fn(&amp;str)-&gt; Result&lt;(&amp;str, &amp;str), nom::Err&lt;nom::error::Error&lt;&amp;str&gt;&gt;&gt; as FnOnce&lt;(&amp;str,)&gt;&gt;::Output`
  </code></pre>
  <p>I mean, what found and what expected seems exactly the same to me.</p>
  <p>Could someone help me to figure out what's wrong here?</p>