[][src]Macro core_extensions::callable_impl

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>
}