#type-safe

macro enumcapsulate-macros

Procedural macros for 'enumcapsulate' crate

4 releases (2 breaking)

0.3.0 May 24, 2024
0.2.2 May 23, 2024
0.2.1 May 5, 2024
0.1.0 Jan 22, 2024

#925 in Procedural macros


Used in enumcapsulate

MPL-2.0 license

45KB
778 lines

enumcapsulate-macros

Crates.io Crates.io Crates.io docs.rs

Derive macros for enumcapsulate crate.


Macros

The enumcapsulate-macros proc-macro crate exports the following derive macros:

Derive macro Functionality
AsVariant Umbrella derive macro for AsVariantRef, and AsVariantMut
AsVariantMut Derive impls for enumcapsulate::AsVariantMut<T> for each variant type T
AsVariantRef Derive impls for enumcapsulate::AsVariantRef<T> for each variant type T
Encapsulate Umbrella derive macro for AsVariantMut, AsVariantRef, From, FromVariant, IntoVariant, IsVariant, TryInto, VariantDiscriminant, and VariantDowncast AsVariantMut
From Derive impls for core::convert::From<T> for each variant type T
FromVariant Derive impls for enumcapsulate::FromVariant<T> for each variant type T
IntoVariant Derive impls for enumcapsulate::FromVariant<T> for each variant type T
IsVariant Derive impl for enumcapsulate::IsVariant
TryInto Derive impls for core::convert::TryInto<T> for each variant type T
VariantDiscriminant Derive impl for enumcapsulate::VariantDiscriminant

Macro helper attributes

Most of the derive macros support helper attributes:

#[enumcapsulate(exclude)]

The variant-based derive macros in this crate will perform derives for every single-field variant they find in the enum. This can lead to undesired false positives where a variant like ToBeExcluded unintentionally gets detected as variant of type bool.

Given an enum like this …

struct VariantA {
    // ...
}

struct VariantB {
    // ...
}

#[derive(FromVariant)]
enum Enum {
    VariantA(VariantA),
    VariantB(VariantB),
    ToBeExcluded { flagToBeExcluded: bool },
}

… the following implementations get derived from the code above:

impl FromVariant<VariantA> for Enum {
    // ...
}

impl FromVariant<VariantB> for Enum {
    // ...
}

// Notice how the derive picked up the `is_cool: bool` field
// as an inner variant and generated an impl for it:

impl FromVariant<bool> for Enum {
    // ...
}

Adding #[enumcapsulate(exclude)] to the undesired variant …

#[derive(FromVariant)]
enum Enum {
    // ...
    #[enumcapsulate(exclude)]
    ToBeExcluded { flag: bool },
}

… makes the undesired impl FromVariant<bool> for Enum get omitted.

#[enumcapsulate(include(field = …_)]

The variant-based derive macros in this crate will skip derives for any multi-field variant they find in the enum.

This can lead to undesired false negatives where a variant like ToBeIncluded unintentionally gets detected as variant of type bool.

For tuple variants the field can be specified by its index: #[enumcapsulate(include(field = INDEX))] For struct variants the field can be specified by its name: #[enumcapsulate(include(field = "NAME"))]

Given an enum like this …

struct VariantA {
    // ...
}

struct VariantB {
    // ...
}

struct VariantC {
    // ...
}

#[derive(FromVariant)]
enum Enum {
    VariantA(VariantA),
    ToBeIncludedB(bool, VariantB),
    ToBeIncludedC { flag: bool, variant: VariantC },
}

… the following implementations get derived from the code above:

impl FromVariant<VariantA> for Enum {
    // ...
}

// Notice how the variants `ToBeIncludedB { … }` and `ToBeIncludedC { … }`
// produced no impls, due to having more than one field.

Adding #[enumcapsulate(include(field =))] to the desired variant, with the desired variant field specified …

#[derive(FromVariant)]
enum Enum {
    // ...
    #[enumcapsulate(include(field = 1))]
    ToBeIncludedB(bool, VariantB),
    #[enumcapsulate(include(field = "variant"))]
    ToBeIncludedC { flag: bool, variant: VariantC },
}

… makes the variants have their impl FromVariant<> for Enum get derived as desired:

// ...

impl FromVariant<VariantB> for Enum {
    // ...
}

impl FromVariant<VariantC> for Enum {
    // ...
}

Note however that #[derive(From)] and #[derive(FromVariant)] (at the current time) still won't generate impls for variants with more than one field.

Helper attribute support

Check the matrix below for which derive macros support which helper attributes:

#[enumcapsulate(exclude)] #[enumcapsulate(include(field =))]
AsVariant ✔ supported ✔ supported
AsVariantMut ✔ supported ✔ supported
AsVariantRef ✔ supported ✔ supported
Encapsulate ✔ supported ✔ supported
From ✔ supported ✘ not supported
FromVariant ✔ supported ✘ not supported
IntoVariant ✔ supported ✔ supported
IsVariant ✔ supported ✔ supported
TryInto ✔ supported ✔ supported
VariantDiscriminant ✘ not supported ✘ not supported

Documentation

Please refer to the documentation on docs.rs.

Contributing

Please read CONTRIBUTING.md for details on our code of conduct,
and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

License

This project is licensed under the MPL-2.0 – see the LICENSE.md file for details.

Dependencies

~275–730KB
~17K SLoC