syn icon indicating copy to clipboard operation
syn copied to clipboard

Feature request: add a macro to parse groups with Delimiter::None

Open NicolasLagaillardie opened this issue 4 years ago • 4 comments

In syn::group, parse_group() is the only function that is not included in a macro to parse groups with Delimiter::None and that is pub(crate). Is there another way to access this function? And is there a specific reason to those choices?

NicolasLagaillardie avatar Oct 28 '20 12:10 NicolasLagaillardie

This would also be very useful for my current usecase.

xldenis avatar Nov 04 '20 21:11 xldenis

Does anyone have a workaround for this? I had to build my library on a fork of syn, and this one of the very few apis which are needed to unfork.

xldenis avatar Oct 01 '21 13:10 xldenis

+1 !

It would be great if this could be made a public API.

jhjourdan avatar Oct 06 '22 14:10 jhjourdan

FWIW, the functionality is somehow provided by parse::discouraged::AnyDelimiter. Not as convenient as a macro, but it does the job.

jhjourdan avatar Apr 28 '23 14:04 jhjourdan

That's right, AnyDelimiter is the intended way to parse these groups. https://docs.rs/syn/2/syn/parse/discouraged/trait.AnyDelimiter.html

use syn::parse::discouraged::AnyDelimiter;
use syn::token;

if input.peek(token::Group) {
    let (delimiter, span, grouped) = input.parse_any_delimiter()?;
    assert_eq!(delimiter, Delimiter::None);

    // parse contents
    grouped.parse ...

    // the delim token, if you need it
    let group = token::Group(span.join());
}

In syn 1, you'd instead have needed to write this with a callback as follows, but the way above is preferred because it is able to produce better error messages and integrates more easily with control flow (early return, etc).

// syn 1.x only

if input.peek(token::Group) {
    let group: proc_macro2::Group = input.parse()?;
    assert_eq!(group.delimiter(), Delimiter::None);

    syn::parse::Parser::parse2(
        |grouped: ParseStream| {
            grouped.parse ...
        },
        group.stream(),
    )?;

    // delim token, if you need it
    let group_token = token::Group(group.span());
}

dtolnay avatar Apr 17 '24 20:04 dtolnay