use enumcapsulate::AsVariant;
trait HasAssoc {
type Assoc: Sized;
}
#[derive(Clone)]
pub struct VariantA;
#[derive(Clone)]
pub struct VariantB;
#[derive(Clone)]
pub struct VariantC<'l>(&'l ());
#[derive(Clone)]
pub struct VariantD<const N: usize>([(); N]);
#[derive(Clone)]
pub struct VariantE<T>(T);
#[derive(Clone)]
pub struct VariantF<'l, const N: usize, T>(&'l [T; N]);
#[derive(Clone)]
pub struct VariantT;
impl HasAssoc for VariantT {
type Assoc = ();
}
#[derive(Clone)]
pub struct VariantU;
trait HasT {
type T: Sized;
}
impl HasT for VariantU {
type T = ();
}
#[derive(AsVariant)]
pub enum Enum<'l, const N: usize, T>
where
T: HasAssoc,
{
Unit,
OwnedSpecificType(VariantA),
BorrowedSpecificType(&'l VariantB),
OwnedWithGenericLifetime(VariantC<'l>),
OwnedGenericTypeWithConstParam(VariantD<N>),
OwnedGenericTypeWithTypeParam(VariantE<T>),
OwnedGenericTypeWithMixedParams(VariantF<'l, N, T>),
OwnedGenericParam(T),
BorrowedGenericParam(&'l T),
OwnedAssocTypeOfGenericParam(T::Assoc),
OwnedAssocTypeOfGenericParamBehindCast(<T as HasAssoc>::Assoc),
OwnedAssocTypeOfSpecificTypeBehindCast(<VariantU as HasT>::T),
}
fn main() {
type Subject<'x> = Enum<'x, 42, VariantT>;
let mut subject = Subject::Unit;
let _: Option<VariantA> = subject.as_variant();
let _: Option<&VariantB> = subject.as_variant();
let _: Option<VariantC<'_>> = subject.as_variant();
let _: Option<VariantC<'_>> = subject.as_variant();
let _: Option<<VariantU as HasT>::T> = subject.as_variant();
}