Attribute Macro enpow::extract

source · []
#[extract]
Expand description

The extract attribute attached to an enum turns each variant into a separate struct that then becomes the only field of the variant. It supports generics and variants of every type, with named or unnamed fields or no fields attached. Variants without data are turned into unit structs, variants with unnamed fields get turned into tuple structs, and variants with named fields are transformed into structs, each named after the enum and variant, i.e. EnumVariant. The structs generated inherit the visibility modifier of the target enum. Additionally, doc comments attached to the variants and variant fields are inherited by the generated structs.

In parethesis, the following arguments to extract can be used to specify which variant types to extract. Without any arguments, all variants will be extracted.

  • Unit: Extracts variants without data into unit structs.
  • Single: Extracts variants with a single unnamed field into tuple structs.
  • Unnamed: Extracts variants with multiple unnamed fields into tuple structs.
  • Named: Extracts variants with named fields into structs.
  • All: Extracts all variants into structs.

This example will extract all variants.


#[extract(All)]
enum IpAddress {
    None,
    V4(u8, u8, u8, u8),
    V6(String),
    Multi {
        v4: (u8, u8, u8, u8),
        v6: String,
    },
}

// Using the modified enum variants and its generated structs
IpAddress::None(IpAddressNone);
IpAddress::V4(IpAddressV4(192, 168, 0, 1));
IpAddress::V6(IpAddressV6("::1".into()));
IpAddress::Multi(IpAddressMulti { v4: (192, 168, 0, 1), v6: "::1".into() });
ℹ️ Click to reveal generated code
enum IpAddress {
    None(IpAddressNone),
    V4(IpAddressV4),
    V6(IpAddressV6),
    Multi(IpAddressMulti),
}
 
struct IpAddressNone;
 
struct IpAddressV4(pub u8, pub u8, pub u8, pub u8);
 
struct IpAddressV6(pub String);
 
struct IpAddressMulti {
    pub v4: (u8, u8, u8, u8),
    pub v6: String,
}

This example will extract all variants with multiple unnamed fields or named fields into separate structs.


#[extract(Unnamed, Named)]
enum IpAddress {
    None,
    V4(u8, u8, u8, u8),
    V6(String),
    Multi {
        v4: (u8, u8, u8, u8),
        v6: String,
    },
}

// Using the unmodified enum variants
IpAddress::None;
IpAddress::V6("::1".into());
 
// Using the modified enum variants and its generated structs
IpAddress::V4(IpAddressV4(192, 168, 0, 1));
IpAddress::Multi(IpAddressMulti { v4: (192, 168, 0, 1), v6: "::1".into() });
ℹ️ Click to reveal generated code
enum IpAddress {
    None,
    V4(IpAddressV4),
    V6(String),
    Multi(IpAddressMulti),
}
 
struct IpAddressV4(pub u8, pub u8, pub u8, pub u8);
 
struct IpAddressMulti {
    pub v4: (u8, u8, u8, u8),
    pub v6: String,
}

An additional derive macro attached to the enum should come after extract to make sure the automatically derived implementations match the changed enum structure.

Auto Derives

Attaching the additional attribute extract_derive() below extract adds the specified auto trait derives to the automatically generated types.


#[extract]
#[extract_derive(Clone, Debug, PartialEq)]
enum IpAddress {
    None,
    V4(u8, u8, u8, u8),
    V6(String),
    Multi {
        v4: (u8, u8, u8, u8),
        v6: String,
    },
}

// Using PartialEq and Debug derive
assert_eq!(
    IpAddressMulti { v4: (0, 0, 0, 0), v6: "::".into() },
    IpAddressMulti { v4: (0, 0, 0, 0), v6: "::".into() }
);
ℹ️ Click to reveal generated code
enum IpAddress {
    None(IpAddressNone),
    V4(IpAddressV4),
    V6(IpAddressV6),
    Multi(IpAddressMulti),
}
 
#[derive(Clone, Debug, PartialEq)]
struct IpAddressNone;
 
#[derive(Clone, Debug, PartialEq)]
struct IpAddressV4(pub u8, pub u8, pub u8, pub u8);
 
#[derive(Clone, Debug, PartialEq)]
struct IpAddressV6(pub String);
 
#[derive(Clone, Debug, PartialEq)]
struct IpAddressMulti {
    pub v4: (u8, u8, u8, u8),
    pub v6: String,
}