macro_rules! morph_types {
    (
		@DECL $( #[doc = $doc:expr] )* $vq:vis $name:ident ()
	) => { ... };
    (
		@DECL $( #[doc = $doc:expr] )* $vq:vis $name:ident ( $( $bound_id:ident ),+ )
	) => { ... };
    (
		@IMPL $name:ty : ( $( $bounds:tt )* ) ( $( $where:tt )* )
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
	) => { ... };
    (
		@IMPL_TRY $name:ty : ( $( $bounds:tt )* ) ( $( $where:tt )* )
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
	) => { ... };
    (
		@IMPL $name:ty : () ( $( $where:tt )* )
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
	) => { ... };
    (
		@IMPL_TRY $name:ty : () ( $( $where:tt )* )
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
	) => { ... };
    (
		@IMPL_BOTH $name:ty : ( $( $bounds:tt )* ) ( $( $where:tt )* )
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
	) => { ... };
    (
		$( #[doc = $doc:expr] )* $vq:vis type $name:ident
		$( < $( $bound_id:ident $( : $bound_head:path $( | $bound_tail:path )* )? ),+ > )?
		$(: $type:tt)?
		= |_| -> $outcome:ty { $( $ex:expr )* };
		$( $rest:tt )*
	) => { ... };
    (
		$( #[doc = $doc:expr] )* $vq:vis type $name:ident
		$( < $( $bound_id:ident $( : $bound_head:path $( | $bound_tail:path )* )? ),+ > )?
		$( EXTRA_GENERIC ($extra:ident) )?
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
		$( where $( $where_path:ty : $where_bound_head:path $( | $where_bound_tail:path )* ),* )?;
		$( $rest:tt )*
	) => { ... };
    (
		$( #[doc = $doc:expr] )* $vq:vis type $name:ident
		$( < $( $bound_id:ident $( : $bound_head:path $( | $bound_tail:path )* )? ),+ > )?
		$( EXTRA_GENERIC ($extra:ident) )?
		: Morph
		= |$var:ident: $var_type:ty| -> $outcome:ty { $( $ex:expr )* }
		$( where $( $where_path:ty : $where_bound_head:path $( | $where_bound_tail:path )* ),* )?;
		$( $rest:tt )*
	) => { ... };
    (
		$( #[doc = $doc:expr] )* $vq:vis type $name:ident
		$( < $( $bound_id:ident $( : $bound_head:path $( | $bound_tail:path )* )? ),+ > )?
		$( EXTRA_GENERIC ($extra:ident) )?
		: TryMorph
		= |$var:ident: $var_type:ty| -> Result<$outcome:ty, ()> { $( $ex:expr )* }
		$( where $( $where_path:ty : $where_bound_head:path $( | $where_bound_tail:path )* ),* )?;
		$( $rest:tt )*
	) => { ... };
    () => { ... };
}
Expand description

Create a Morph and/or TryMorph impls with a simple closure-like expression.

Examples


morph_types! {
   /// Replace by some other value; produce both `Morph` and `TryMorph` implementations
   pub type Replace<V: TypedGet> = |_| -> V::Type { V::get() };
   /// A private `Morph` implementation to reduce a `u32` by 10.
   type ReduceU32ByTen: Morph = |r: u32| -> u32 { r - 10 };
   /// A `TryMorph` implementation to reduce a scalar by a particular amount, checking for
   /// underflow.
   pub type CheckedReduceBy<N: TypedGet>: TryMorph = |r: N::Type| -> Result<N::Type, ()> {
       r.checked_sub(&N::get()).ok_or(())
   } where N::Type: CheckedSub;
}

trait Config {
   type TestMorph1: Morph<u32>;
   type TestTryMorph1: TryMorph<u32>;
   type TestMorph2: Morph<u32>;
   type TestTryMorph2: TryMorph<u32>;
}

struct Runtime;
impl Config for Runtime {
   type TestMorph1 = Replace<ConstU32<42>>;
   type TestTryMorph1 = Replace<ConstU32<42>>;
   type TestMorph2 = ReduceU32ByTen;
   type TestTryMorph2 = CheckedReduceBy<ConstU32<10>>;
}