The contextual macros
This library introduces a proc macro def_impls!{}
in which you can define an
enum and write several impl blocks. In these impl blocks, the following macros
are supported:
-
_Variants!()
in where clause. For example,where _Variants!(): SomeTrait
means each variant has the trait bound of: SomeTrait
. -
_match!()
in trait method. This macro will expand to a match expression that enumerate all variants, and translate the macros listed below. -
_variant!()
in_match!()
. This macro will expand to the value of the matched variant. -
_Variant!()
in_match!()
. This macro will expand to the type of the matched variant. -
_enum!()
in_match!()
. This macro will wrap its inner value to get an enum. Use this macro if the trait method returnsSelf
.
Examples
Let's rewrite the generic enum example:
#![allow(unused)] fn main() { def_impls! { impl<T0,T1> AsRef<[u8]> for Enum2<T0,T1> where _Variants!(): AsRef<[u8]> { fn as_ref( &self ) -> &[u8] { _match!( _variant!().as_ref() ) } } } }
Another example, implementing Clone. Note the using of _enum!()
.
#![allow(unused)] fn main() { def_impls! { impl<T0,T1> Clone for Enum2<T0,T1> where _Variants!(): Clone { fn clone( &self ) -> Self { _match!( _enum!( _variant!().clone() ) ) } } } }
You can specify the expression matched
being matched, using the syntax
_match!( matched => expr )
. If ommited, _match!( expr )
is equivalent to
_match!( self => expr )
.
#![allow(unused)] fn main() { def_impls! { impl<T0, T1, R, Yield, Return> std::ops::Generator<R> for Enum2<T0,T1> where _Variants!(): std::ops::Generator<R,Yield=Yield,Return=Return> { type Yield = Yield; type Return = Return; fn resume( self: std::pin::Pin<&mut Self>, arg: R ) -> std::ops::GeneratorState<Self::Yield, Self::Return> { _match!( unsafe{ self.get_unchecked_mut() } => unsafe{ std::pin::Pin::new_unchecked( _variant!() )} .resume( arg ) ) } } } }