//! Traits and macro to use newtype enums and convert between enums and their variants.
//!
//! A newtype enum is an enum where every variant wraps another type and the wrapped type can uniquely identify the variant.
//!
//! You can use the [`newtype_enum`](attr.newtype_enum.html) attribute macro to define a newtype enum. When the macro is applied to an enum `E` it will implement the [`Enum`](trait.Enum.html) trait for `E` and the [`Variant<E>`](trait.Variant.html) trait for all variant types.
//!
//! See the [**examples in the `Enum` trait**](trait.Enum.html) for usage of the available methods.
//!
//! The macro will also convert all unit and struct variants to generated structs and replace the enum variant with a newtype variant that contains the generated struct. See below for the rules and options that are available.
//!
//! # Variant transformation
//! The variants of the enum will be converted in the following way:
//!
//! ## Unit variants
//! ```
//! # use newtype_enum::newtype_enum;
//! #[newtype_enum]
//! enum Test {
//! Example,
//! }
//! ```
//! ```
//! enum Test {
//! Example(Test_variants::Example),
//! }
//!
//! mod Test_variants {
//! pub(super) struct Example;
//! }
//! ```
//!
//! ## Newtype variants
//! ```
//! # use newtype_enum::newtype_enum;
//! #[newtype_enum]
//! enum Test {
//! Example(usize),
//! }
//! ```
//! ```
//! enum Test {
//! Example(usize),
//! }
//! ```
//! ## Struct variants
//! ```
//! # use newtype_enum::newtype_enum;
//! #[newtype_enum]
//! enum Test {
//! Example { test: usize },
//! }
//! ```
//! ```
//! enum Test {
//! Example(Test_variants::Example),
//! }
//!
//! mod Test_variants {
//! pub(super) struct Example {
//! pub(super) test: usize,
//! }
//! }
//! ```
//!
//! # Attribute arguments
//! You can pass the following arguments to the `newtype_enum` macro:
//!
//! ## Variants module name
//! ```
//! # use newtype_enum::newtype_enum;
//! #[newtype_enum(variants = "test")]
//! enum Test {
//! Example,
//! }
//! ```
//! ```
//! enum Test {
//! Example(test::Example),
//! }
//!
//! mod test {
//! // <-- the name of the generated module
//! pub(super) struct Example;
//! }
//! ```
//! ## Variants module visibility
//! ```
//! # use newtype_enum::newtype_enum;
//! #[newtype_enum(variants = "pub(crate) test")]
//! enum Test {
//! Example,
//! }
//! ```
//! ```
//! enum Test {
//! Example(test::Example),
//! }
//!
//! pub(crate) mod test {
//! // <-- the visibility of the generated module
//! pub(super) struct Example;
//! }
//! ```
//!
//! # Visibilities and attributes (e.g. `#[derive]` attributes)
//! The visibility of the generated variant structs behaves as if they where part of a normal enum: All variants and their fields have the same visibiltiy scope as the enum itself.
//!
//! Attributes will be passed to the following locations:
//!
//! Location | Destination
//! -|-
//! enum | Enum and generated variant structs
//! enum variant | Generated variant struct
//! variant field | Generated struct field
//!
//! ```
//! # mod test {
//! # use newtype_enum::newtype_enum;
//! #[newtype_enum]
//! #[derive(Debug)]
//! pub(crate) enum Test {
//! #[derive(Clone)]
//! Example {
//! test: usize,
//! pub(super) test_super: usize,
//! pub(self) test_self: usize,
//! },
//! }
//! # }
//! ```
//! ```
//! # mod test {
//! #[derive(Debug)]
//! pub(crate) enum Test {
//! Example(Test_variants::Example),
//! }
//!
//! pub(crate) mod Test_variants {
//! #[derive(Debug, Clone)]
//! pub(crate) struct Example {
//! pub(crate) test: usize,
//! pub(in super::super) test_super: usize,
//! pub(super) test_self: usize,
//! }
//! }
//! # }
//! ```
/// Define a newtype enum.
///
/// See [crate-level documentation](index.html) for more information.
pub use newtype_enum;
/// Mark a type as an `enum`.
///
/// Use the [`newtype_enum`](attr.newtype_enum.html) macro to implement this trait for your enum types.
///
/// ```
/// # use newtype_enum::newtype_enum;
/// #[newtype_enum(variants = "pub example")]
/// #[derive(Debug)]
/// # #[derive(PartialEq, Eq)]
/// pub enum Test {
/// Ping,
/// Number(usize),
/// Str(&'static str),
/// #[derive(Clone)]
/// Hello {
/// name: &'static str,
/// },
/// }
///
/// use newtype_enum::Enum;
///
/// let test = Test::from_variant(example::Hello { name: "Tester" });
/// println!("{:?}", test);
///
/// let variant: example::Hello = test.into_variant().unwrap();
/// let cloned = variant.clone();
/// assert_eq!(variant, cloned);
/// ```
/// Mark a type as a newtype variant of an [`Enum`](trait.Enum.html) `E`.
///
/// Use the [`newtype_enum`](attr.newtype_enum.html) macro to implement this trait for your enum variants.