/parse-variants

Derive the Parse trait for enums and use it to comfortably parse either variant of the enum.

Primary LanguageRustMIT LicenseMIT

parse-variants

build lints tests approval-tests maintenance-status

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

Support

If you like this crate, recommend it to others. You can also buy me a coffee if you feel like it.

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.