title: Keep the LocatedSpan of an "outer" parser with nom in Rust
body: <p>I am trying to write a parser using the <code>nom</code> crate (and the <code>nom_locate</code>) that can parse strings such as <code>u{12a}</code>, i.e.:</p>
  <pre><code>u\{([0-9a-fA-F]{1,6})\}
  </code></pre>
  <p>I wrote the following parser combinator:</p>
  <pre class="lang-rust prettyprint-override"><code>use nom::bytes::complete::{take_while_m_n};
  use nom::character::complete::{char};
  use nom::combinator::{map_opt, map_res};
  
  use nom::sequence::{delimited, preceded};
  
  
  pub type LocatedSpan&lt;'a&gt; = nom_locate::LocatedSpan&lt;&amp;'a str&gt;;
  pub type IResult&lt;'a, T&gt; = nom::IResult&lt;LocatedSpan&lt;'a&gt;, T&gt;;
  
  #[derive(Clone, Debug)]
  pub struct LexerError&lt;'a&gt;(LocatedSpan&lt;'a&gt;, String);
  
  fn expect&lt;'a, F, E, T&gt;(
      mut parser: F,
      err_msg: E,
  ) -&gt; impl FnMut(LocatedSpan&lt;'a&gt;) -&gt; IResult&lt;Option&lt;T&gt;&gt;
  where
      F: FnMut(LocatedSpan&lt;'a&gt;) -&gt; IResult&lt;T&gt;,
      E: ToString,
  {
      use nom::error::Error as NomError;
      move |input| match parser(input) {
          Ok((remaining, output)) =&gt; Ok((remaining, Some(output))),
          Err(nom::Err::Error(NomError { input, code: _ }))
          | Err(nom::Err::Failure(NomError { input, code: _ })) =&gt; {
              let err = LexerError(input, err_msg.to_string());
              // TODO Report error.
              println!(&quot;error: {:?}&quot;, err);
              Ok((input, None))
          }
          Err(err) =&gt; Err(err),
      }
  }
  
  fn lit_str_unicode_char(input: LocatedSpan) -&gt; IResult&lt;char&gt; {
      let parse_hex = take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit());
      // FIXME Figure out a way to keep correct span here.
      let parse_delim_hex = preceded(
          char('u'),
          delimited(
              char('{'),
              expect(parse_hex, &quot;expected 1-6 hex digits&quot;),
              expect(char('}'), &quot;expected closing brace&quot;),
          ),
      );
      let parse_u32 = map_res(parse_delim_hex, move |hex| match hex {
          None =&gt; Err(&quot;cannot parse number&quot;),
          Some(hex) =&gt; match u32::from_str_radix(hex.fragment(), 16) {
              Ok(val) =&gt; Ok(val),
              Err(_) =&gt; Err(&quot;invalid number&quot;),
          },
      });
      map_opt(parse_u32, std::char::from_u32)(input)
  }
  
  fn main() {
      let raw = &quot;u{61}&quot;;
      let span = LocatedSpan::new(raw);
      let result = lit_str_unicode_char(span);
      println!(&quot;{:#?}&quot;, result);
  }
  </code></pre>
  <p>This works correctly, I am able to get the Unicode character out of the string. However, this approach does not keep the proper spans, i.e.:</p>
  <pre><code>u{123}
  \..../  &lt;--- the span I want
       \/ &lt;--- the span I get
  </code></pre>
  <p>I figured I could wrap the <code>parse_delim_hex</code> in a <code>recognize</code>, which would keep the span correctly, but then I couldn't use the following parsers to &quot;understand&quot; the digits.</p>
  <p>How should I get around this issue?</p>