pub(crate) fn derive_is_bit_valid(
enum_ident: &Ident,
repr: &Repr<PrimitiveRepr, Infallible>,
generics: &Generics,
data: &DataEnum,
zerocopy_crate: &Path,
) -> Result<TokenStream, Error>Expand description
Generates an implementation of is_bit_valid for an arbitrary enum.
The general process is:
- Generate a tag enum. This is an enum with the same repr, variants, and
corresponding discriminants as the original enum, but without any fields
on the variants. This gives us access to an enum where the variants have
the same discriminants as the one we’re writing
is_bit_validfor. - Make constants from the variants of the tag enum. We need these because we can’t put const exprs in match arms.
- Generate variant structs. These are structs which have the same fields as
each variant of the enum, and are
#[repr(C)]with an optional “inner tag”. - Generate a variants union, with one field for each variant struct type.
- And finally, our raw enum is a
#[repr(C)]struct of an “outer tag” and the variants union.
See these reference links for fully-worked example decompositions.
repr(C): https://doc.rust-lang.org/reference/type-layout.html#reprc-enums-with-fieldsrepr(int): https://doc.rust-lang.org/reference/type-layout.html#primitive-representation-of-enums-with-fieldsrepr(C, int): https://doc.rust-lang.org/reference/type-layout.html#combining-primitive-representations-of-enums-with-fields-and-reprc