Attribute Macro tylift::tylift [−][src]
#[tylift]
The attribute promotes enum variants to their own types.
The enum type becomes a kind
– the type of a type – emulated by a trait, replacing the original type declaration.
In Rust, the syntax of trait bounds (:
) beautifully mirror the syntax of type annotations.
Thus, the snippet B: Bool
can also be read as “type parameter B
of kind Bool
”.
Traits representing kinds are sealed, which means nobody is able to add new types to
the kind. Variants can hold (unnamed) fields of types of a given kind.
Attributes (notably documentation comments) applied to the item itself and its variants will
be preserved. Expanded code works in #![no_std]
-environments.
As of right now, there is no automated way to reify the lifted variants (i.e. map them to their term-level counterpart). Lifted enum types can not be generic over kinds. Attributes placed in front of fields of a variant (constructor arguments) will not be translated and thus have no effect.
Examples:
use tylift::tylift; use std::marker::PhantomData; #[tylift] pub enum Mode { Safe, Fast, } pub struct Text<M: Mode> { content: String, _marker: PhantomData<M>, } impl<M: Mode> Text<M> { pub fn into_inner(self) -> String { self.content } } impl Text<Safe> { pub fn from(content: Vec<u8>) -> Option<Self> { Some(Self { content: String::from_utf8(content).ok()?, _marker: PhantomData, }) } } impl Text<Fast> { pub unsafe fn from(content: Vec<u8>) -> Self { Self { content: unsafe { String::from_utf8_unchecked(content) }, _marker: PhantomData, } } } fn main() { let safe = Text::<Safe>::from(vec![0x73, 0x61, 0x66, 0x65]); let fast = unsafe { Text::<Fast>::from(vec![0x66, 0x61, 0x73, 0x74]) }; assert_eq!(safe.map(Text::into_inner), Some("safe".to_owned())); assert_eq!(fast.into_inner(), "fast".to_owned()); } #[tylift] pub enum Bool { False, True, } #[tylift] pub(crate) enum Nat { Zero, Succ(Nat), } #[tylift] enum BinaryTree { Leaf, Branch(BinaryTree, Nat, BinaryTree), } #[tylift(mod)] // put the all 3 items into the module `Power` pub enum Power { On, Off, } #[tylift(mod direction)] // put all 3 items into the module `direction` pub(crate) enum Direction { /// Higher and higher! Up, /// Lower and lower... Down, }