#![doc = include_str!("README.md")]
/// This attribute macro implements trait [`Flat`] on the speficied enum. The definition body
/// should be empty, thus it is generated from corresponding structured enum automatically.
///
/// ```
/// # use flat_enum::{flat, into_flat, FlatTarget};
/// # #[derive(FlatTarget)]
/// # pub enum Enum1 {
/// # E1(A),
/// # E2(),
/// # E3(String),
/// # }
/// #[into_flat(Enum2Flat)]
/// pub enum Enum2 {
/// #[flatten]
/// Enum1(Enum1),
/// E4,
/// }
///
/// #[flat(Enum2)]
/// pub enum Enum2Flat {}
/// ```
///
/// ## Arguments
///
/// Specify the coresponding structured enum (which has [`IntoFlat`] trait implementation)
/// as the first arguments.
/// The flat enum should be exist in the same context (same module, function, or block context).
///
/// You can specify the `flat_enum` crate using atmark syntax like
/// `#[flat(Enum2 @ ::flat_enum)]`.
pub use flat_enum_macro::flat;
/// This attribute macro implements trait [`IntoFlat`] on the speficied enum.
///
/// ```
/// # use flat_enum::{flat, into_flat, FlatTarget};
/// # #[derive(FlatTarget)]
/// # pub enum Enum1 {
/// # E1(A),
/// # E2(),
/// # E3(String),
/// # }
/// #[into_flat(Enum2Flat)]
/// pub enum Enum2 {
/// #[flatten]
/// Enum1(Enum1),
/// E4,
/// }
///
/// #[flat(Enum2)]
/// pub enum Enum2Flat {}
/// ```
///
/// ## Arguments
///
/// Specify the flat enum (which has [`Flat`] trait implementation implemented with [`flat`]
/// macro) as the first arguments.
/// The flat enum should be exist in the same context (same module, function, or block context).
///
/// You can specify the `flat_enum` crate using atmark syntax like
/// `#[into_flat(Enum2Flat @ ::flat_enum)]`.
///
/// ## `#[flatten]` attribute
///
/// Due to the effect of `#[into_flat]` macro, variants defined with `#[flatten]`
/// attribute is expanded in the corresponding flat enum. The variant should have tuple-like
/// fields, and just one field with type, which has [`FlatTarget`] trait implementation defined
/// with `#[derive(FlatTarget)]`.
pub use flat_enum_macro::into_flat;
/// Implements trait [`FlatTarget`] on the specified enum. This trait is required to be
/// used as the field type of nesting enum variant augmented with `#[flatten]` attribute
/// in `#[into_flat]` enum.
pub use flat_enum_macro::FlatTarget;
/// Marker trait implemented with `#[derive(FlatTarget)]`.
pub unsafe trait FlatTarget {}
/// Leak `N`th type used in enum variants.
#[doc(hidden)]
pub unsafe trait Leak: FlatTarget {
type Ty;
}
/// See [`into_flat`]
pub unsafe trait IntoFlat {
type Flat: Flat;
fn into_flat(self) -> Self::Flat;
fn from_flat(_: Self::Flat) -> Self;
}
/// See [`flat`]
pub unsafe trait Flat {
type Structured: IntoFlat;
}
#[cfg(feature = "testing")]
pub mod testing {
use super::FlatTarget;
#[derive(FlatTarget)]
pub enum Enum6<'a, const N: usize, A> {
E8(&'a [A; N]),
}
}