[][src]Macro vulkayes_core::unsafe_enum_variants

macro_rules! unsafe_enum_variants {
    (
		$(#[$attribute: meta])*
		enum $inner_name: ident $([ $($generic_bounds: tt)+ ])? {
			$(
				$(#[$variant_attribute: meta])*
				$({$safety: tt})? $v: vis $variant: ident $({
					 $($variant_name: ident: $variant_type: ty),+ $(,)?
				})? => { $($into_code: tt)+ }
			),+ $(,)?
		} as pub $name: ident $([ $($generic_params: tt)+ ])? impl Into<$into_type: ty>
	) => { ... };
    (
		$(#[$attribute: meta])*
		enum $inner_name: ident $([ $($generic_bounds: tt)+ ])? {
			$(
				$(#[$variant_attribute: meta])*
				$({$safety: tt})? $v: vis $variant: ident $({
					 $($variant_name: ident: $variant_type: ty),+ $(,)?
				})?
			),+ $(,)?
		} as pub $name: ident $([ $($generic_params: tt)+ ])?
	) => { ... };
}

Generates a private enum and a public newtype struct that only has that enum as a value. Also generated constructors on the struct that match the enum variants.

This is useful for making certain enum variants "unsafe" by only allowing their construction using an unsafe function. Variants may also be private.

Since a common usecase across this crate for this macro are typesafe parameter combinations, there is also a version with Into implementation.

Tuple enum variants are not supported.

Usage:

unsafe_enum_variants! {
	#[derive(Debug)]
	enum UnsafeEnumInner ['a] {
		/// Private
		Foo => { &0u32 },
		/// Public
		pub Bar => { &1u32 },
		/// Unsafe and generic
		{unsafe} pub Qux { num: &'a u32 } => { num }
	} as pub UnsafeEnum ['a] impl Into<&'a u32>
}

expands to:

#[derive(Debug)]
enum UnsafeEnumInner<'a> {
	Foo,
	Bar,
	Qux {
		num: &'a u32
	}
}
#[derive(Debug)]
pub struct UnsafeEnum<'a>(UnsafeEnumInner<'a>);
impl<'a> UnsafeEnum<'a> {
	#[doc = r###"Private"###]
	#[allow(non_snake_case)]
	const fn Foo() -> Self {
		UnsafeEnum(UnsafeEnumInner::Foo)
	}
	#[doc = r###"Public"###]
	#[allow(non_snake_case)]
	pub const fn Bar() -> Self {
		UnsafeEnum(UnsafeEnumInner::Bar)
	}
	#[doc = r###"Unsafe"###]
	#[allow(non_snake_case)]
	pub const unsafe fn Qux(num: &'a u32) -> Self {
		UnsafeEnum(UnsafeEnumInner::Qux { num })
	}
}
impl<'a> Into<&'a u32> for UnsafeEnum<'a> {
	fn into(self) -> &'a u32 {
		match self.0 {
			UnsafeEnumInner::Foo => { &0u32 },
			UnsafeEnumInner::Bar => { &1u32 },
			UnsafeEnumInner::Qux { num } => { num }
		}
	}
}