macro_rules! try_parse_quote_spanned {
    ($span:expr => $($tt:tt)*) => { ... };
}
Expand description

Similar to syn::parse_quote_spanned!, but instead of panicking, it returns an Err if the inferred type fails to parse from the specified token stream.

use parsel::{parse_str, try_parse_quote_spanned, Result};
use parsel::ast::{word, Word, Punctuated};
use parsel::ast::token::Comma;

fn try_parse_words(interp: &str, spanner: &str) -> Result<Punctuated<Word, Comma>> {
    let interp: Word = parse_str(interp)?;
    let spanner: Word = parse_str(spanner)?;

    // Interpolated tokens must preserve their own span, whereas
    // tokens originating from the macro will have the specified span.
    let ast = try_parse_quote_spanned!{ spanner.span() =>
        lorem, #interp, ipsum
    };

    Ok(ast)
}

let interp = "quodsit";
let spanner = "this_is_a_long_identifier";

let actual = try_parse_words(interp, spanner)?;
let expected_strings = ["lorem", interp, "ipsum"];
let expected: Punctuated<Word, Comma> = expected_strings
    .iter()
    .copied()
    .map(word)
    .collect();

let actual_ends: Vec<_> = actual
    .iter()
    .map(|w| w.span().end().column)
    .collect();
let expected_ends = vec![spanner.len(), interp.len(), spanner.len()];

assert_eq!(actual, expected);
assert_eq!(actual_ends, expected_ends);