Macro core_extensions::callable_impl [−][src]
macro_rules! callable_impl { ( $(#[$meta:meta])* fn $fn_kind:ident $( [ $( $fn_gen_params:tt )* ] )* ( $( $fn_params:tt )* ) $( ->$ret_ty:ty )* $( where [ $( $where_preds:tt )* ] )* { $( $fn_contents:tt )* } ) => { ... }; (inner_param; $param:expr $(,)* ) => { ... }; (inner_param; $param:expr , $param0:ident : $param0_ty:ty $(,)* ) => { ... }; (inner_param; $param:expr , $( $params:ident : $params_ty:ty ),+ $(,)* ) => { ... }; (inner_param_ty; $(,)* ) => { ... }; (inner_param_ty; $param0:ident : $param0_ty:ty $(,)* ) => { ... }; (inner_param_ty; $( $params:ident : $params_ty:ty ),+ $(,)* ) => { ... }; (inner_fn; $(#[$meta:meta])* fn call_into [ $( $fn_gen_params:tt )* ] ( $self_:ident:$fn_ty:ty $(=> $($rem_param:tt)* )* ) $(->$ret_ty:ty)* where [ $( $where_preds:tt )* ] { $( $fn_contents:tt )* } ) => { ... }; (inner_fn; $(#[$meta:meta])* fn call_mut [ $( $fn_gen_params:tt )* ] ( $self_:ident:$fn_ty:ty $(=> $($rem_param:tt)* )* ) $(->$ret_ty:ty)* where [ $( $where_preds:tt )* ] { $( $fn_contents:tt )* } ) => { ... }; (inner_fn; $(#[$meta:meta])* fn call_ref [ $( $fn_gen_params:tt )* ] ( $self_:ident:$fn_ty:ty $(=> $($rem_param:tt)* )* ) $(->$ret_ty:ty)* where [ $( $where_preds:tt )* ] { $( $fn_contents:tt )* } ) => { ... }; }
This macro allows more ergonomically implementing the Call(Ref|Mut|Into) traits .
Examples
Implementing CallRef. The lifetime is written out explicitly because this macro desugars to impl blocks,which don't elide lifetime parameters in Rust 2015 edition.
struct Environment; callable_impl!{ fn call_ref['a](this:Environment => printing:&'a str ){ println!("printing '{}'",printing); } } Environment.call_ref("what the ...");
Implementing CallMut. Also demonstrates a polymorphic function, not possible in Rust closures until it gets higher ranked closures.
struct Environment{ i:u16, } callable_impl!{ fn call_mut[T](this:Environment => _a:VariantPhantom<T>)->T where [ u16:Into<T>, ] { this.i+=1; this.i.into() } } let mut env=Environment{i:0}; assert_eq!(env.call_mut(u16::T),1); assert_eq!(env.call_mut(u32::T),2);
Implementing CallInto.
struct Environment<T>(T); callable_impl!{ fn call_into[T](this:Environment<T>)->T{ this.0 } } let env=Environment("hello"); assert_eq!(env.call_into(()),"hello");
Syntax
$( ... )*
means repeated 0 or more times.
$( ... )+
means repeated 1 or more times.
$( ... )?
means that this is optional.
< ... >
is a variable,replaced with whatever it refers to.
$(#[$meta:meta])*
// <fn_method_name> is one of (call_into|call_mut|call_ref),determining which trait
// is implemented.
fn <fn_method_name>
// Optionally declares the generic parameters of the function.
$( [ $( <generic_parameter> )* ] )?
// <self_ident> is the identifier used to access the closure environment.
// <self_type> is the type of the closure environment,which is implementing the Call traits.
// <function_parameter> are optional function parameters.
( <self_ident>:<self_type>
$( => $( <function_parameter> ),* )?
)
//<return_tyoe> optional return type,defaults to '()'.
$( -><return_type> )?
// An optional where clause,
// all tokens inside `[...]` get copied directly to the where clause of the impl.
$( where [ $( <where_predicates> )* ] )*
{
// The definition of the function
<function_definition>
}