[][src]Macro tagged_box::tagged_box

macro_rules! tagged_box {
    (
        $( #[$meta:meta] )*
        $struct_vis:vis struct $struct:ident, $enum_vis:vis enum $enum:ident {
            $( $variant:ident($ty:ty), )+
        }
    ) => { ... };
}

Constructs a wrapper type and an associated enum to be stored as a TaggedBox that can be used safely.
For more implementation details, see manually implementing a tagged enum

Example Usage

tagged_box! {
    #[derive(Debug, Clone, PartialEq)] // This will be applied to both the inner enum and outer container
    struct Container, enum Item {
        Integer(i32),
        Boolean(bool),
        String(String),
    }
}

Note: The number of variants must be <= MAX_DISCRIMINANT

This will create a struct Container and an enum Item. Expanded, they will look like this:

#[derive(Debug, Clone, PartialEq)]
#[repr(transparent)] // repr(transparent) is automatically added to the generated structs
struct Container {
    value: TaggedBox<Item>,
}

#[derive(Debug, Clone, PartialEq)]
enum Item {
    Integer(i32),
    Boolean(bool),
    String(String),
}

// ..Omitted some generated code

The omitted code will contain From implementations that allow you to get a Container from any value that would be allowed to be inside of the Item enum, e.g.

This example deliberately fails to compile
Container::from(10i32);         // Works!
Container::from(String::new()); // Works!
Container::from(Vec::new());    // Doesn't work :(

With your freshly created container, you can now store an enum on the stack with only usize bytes of memory and safely retrieve it.

To get the value of a Container instance, simply use into_inner after importing the TaggableContainer trait

use tagged_box::TaggableContainer;

let container = Container::from(String::from("Hello from tagged-box!"));
assert_eq!(container.into_inner(), Item::String(String::from("Hello from tagged-box!")));