Macro namable_closures::closure[][src]

macro_rules! closure {
    ($state:ident=$state_val:expr => move || $body:expr) => { ... };
    ($state:ident=$state_val:expr => move |$arg:pat| $body:expr) => { ... };
    ($state:ident=$state_val:expr => move |$arg1:pat,$($arg2:pat),+| $body:expr) => { ... };
    (mut $state:ident=$state_val:expr => move || $body:expr) => { ... };
    (mut $state:ident=$state_val:expr => move |$arg:pat| $body:expr) => { ... };
    (mut $state:ident=$state_val:expr => move |$arg1:pat,$($arg2:pat),+| $body:expr) => { ... };
    (mut $state:ident=$state_val:expr => || $body:expr) => { ... };
    (mut $state:ident=$state_val:expr => |$arg:pat| $body:expr) => { ... };
    (mut $state:ident=$state_val:expr => |$arg1:pat,$($arg2:pat),+| $body:expr) => { ... };
    (ref mut $state:ident=$state_val:expr => move || $body:expr) => { ... };
    (ref mut $state:ident=$state_val:expr => move |$arg:pat| $body:expr) => { ... };
    (ref mut $state:ident=$state_val:expr => move |$arg1:pat,$($arg2:pat),+| $body:expr) => { ... };
    ($state:ident=$state_val:expr => || $body:expr) => { ... };
    ($state:ident=$state_val:expr => |$arg:pat| $body:expr) => { ... };
    ($state:ident=$state_val:expr => |$arg1:pat,$($arg2:pat),+| $body:expr) => { ... };
    (ref $state:ident=$state_val:expr => move || $body:expr) => { ... };
    (ref $state:ident=$state_val:expr => move |$arg:pat| $body:expr) => { ... };
    (ref $state:ident=$state_val:expr => move |$arg1:pat,$($arg2:pat),+| $body:expr) => { ... };
    (ref $state:ident=$state_val:expr => |$($arg:pat),*| $body:expr) => { ... };
    (ref mut $state:ident=$state_val:expr => |$($arg:pat),*| $body:expr) => { ... };
}

The macro to create closures.

Examples:

// state refered as reference in body, but moved to the closure
let add_ten:ClosureRef<i32,(i32,),i32>
    = closure!(ref state=10 => move |i| i+*state);
assert_eq!(add_ten.stable_call((1,)),11);
let offset:ClosureRef<Point,(i32,i32),Point>
    = closure!(ref state=Point::new(10,20) => move |a,b| Point::new(state.x+a,state.y+b));
let p = offset.stable_call_once((1,2));
assert_eq!(p.x,11);
assert_eq!(p.y,22);

// state refered as reference in body, and not moving
let state = 10;
let add_ten:Closure<i32,(i32,),i32>
    = closure!(state=&state => |i| i+10);
assert_eq!(add_ten.stable_call((1,)),11);
let state = Point::new(10,20);
let offset:Closure<Point,(i32,i32),Point>
    = closure!(state=&state => |a,b| Point::new(state.x+a,state.y+b));
let p = offset.stable_call_once((1i32,2i32));
assert_eq!(p.x,11);
assert_eq!(p.y,22);

// state refered as mutable reference in body, but moved to closure
let mut accumulate:ClosureRefMut<i32,(i32,),i32>
    = closure!(ref mut state=0 => move |c| {*state+=c;*state});
assert_eq!(accumulate.stable_call_mut((1,)),1);
assert_eq!(accumulate.stable_call_once((2,)),3);

// state refered as mutable reference in body, but not moving
let mut state = 0;
{
  let mut match_cnt:ClosureMut<i32,(i32,i32),()>
      = closure!(mut state=&mut state => |a,b| if a==b { *state+=1 });
  for i in 0..10 { match_cnt.stable_call_mut((i,i*3%10)); }
}
assert_eq!(state,2);

// state moved to body and so to the closure
let sign_on:ClosureOnce<Passwd,(String,),Result<(),io::Error>>
    = closure!(passwd=Passwd::get_from_cache() => move |user| authenticate(user,passwd));
let auth:ClosureOnce<RoleSet,(String,Passwd),Result<(),io::Error>>
    = closure!(role_set=RoleSet::from_config() => move |user,passwd| check_user(role_set,user,passwd));
let send_data:ClosureOnce<MyStream,(&[u8],),Result<usize,io::Error>>
    = closure!(mut stream=MyStream::new() => move |data| stream.write_all(data));
let read_data:ClosureOnce<MyStream,(&mut [u8],usize),Result<(),io::Error>>
    = closure!(mut stream=MyStream::new() => move |buf,len| stream.read_exact_ex(buf, len));