#macro-derive #enums #parse #variant #parser #speculative

parse-variants

Derive the syn::parse::Parse trait for enumerations and use it to comfortably parse a variant of the enumeration

7 releases (stable)

1.0.4 Dec 1, 2024
1.0.3 Jul 27, 2024
1.0.1 Mar 20, 2023
0.1.1 Jun 12, 2021

#47 in Procedural macros

Download history 1164/week @ 2024-08-18 966/week @ 2024-08-25 1671/week @ 2024-09-01 1474/week @ 2024-09-08 674/week @ 2024-09-15 652/week @ 2024-09-22 604/week @ 2024-09-29 565/week @ 2024-10-06 878/week @ 2024-10-13 824/week @ 2024-10-20 699/week @ 2024-10-27 495/week @ 2024-11-03 552/week @ 2024-11-10 1024/week @ 2024-11-17 534/week @ 2024-11-24 1067/week @ 2024-12-01

3,311 downloads per month
Used in 76 crates (7 directly)

MIT license

19KB
225 lines

parse-variants

build lints tests approval-tests maintenance-status crates

Derive the syn::parse::Parse trait for enumerations and use it to comfortably parse a variant of the enumeration.

Motivation

For a little project, I was trying to parse tokens that could either be an integer literal or an identifier from a ParseBuffer. This inspired me to write a custom derive macro for these kinds of use cases. We can now write

#[derive(parse_variants::Parse)]
enum Number {
    Identifier(syn::Ident),
    Literal(syn::LitInt),
}

and then use this type to parse either variant from a parse buffer like so:

// input : &ParseBuffer
let num : Number = input.parse()?;

This operation returns the first variant (in order of declaration) that can be successfully parsed from the contents of the parse buffer. If none of the variants can be parsed, a compile error is returned. We can use this in any context where we wish to parse this type. The custom derive macro can also be used on much more general enum types, enabling pretty powerful parsing of variant types.

Advanced Use Cases

Enumerations do not have to be as simple as in the example above, because this crate will let you use the custom derive on enumerations with struct-like or tuple-like variants (or any combination of them). See this silly example for a more advanced use case:

mod kw {
    syn::custom_keyword!(meters);
}

#[derive(parse_variants::Parse)]
enum SillyEnum {
    ExpressionInMeters {
        first: syn::Expr,
        _meters: kw::meters,
    },
    IdentPlusPlus(Ident, syn::Token![+], syn::Token![+]),
}

This parses the tokens 16 + 12*length meters as the first and C++ as the second variant.

Consult the crate documentation for more information on how to use this macro and what to watch out for.

Dependencies

~215–650KB
~15K SLoC