Crate namable_closures[][src]

This crate supports nameable closures, without requiring any language changes.

Why do we need this

The Rust language supports closures, however its concret types are anonymous and developers cannot expect same size, and so not able to put similar closures in containers that requires Sized constraint.

However, there is an exception: if a closure does not refer to its captured variables, it can be coerce to a fn type, which is a pointer type and it is Sized.

This library extends this idea by requesting an additional State field, which is just the tuple of the captured variables. So if two closure have the same signiture for function calls and have the same state type, they are considered the same type.

How to use

There are 5 structures being defined, and they are correspond to different use cases.

Closure

This struct works for closures that only intended to refer to the state field, not modifying them nor owns them. However, it does own its state, so dropping this struct will drop its state as well.

This struct is created by a macro closure!.

Example:

let add_ten:Closure<i32,(i32,),i32> = closure!(state, i,  i+*state, 10);
assert_eq!(add_ten(1),11);
let offset:Closure<Point,(i32,i32),Point>
    = closure!(state, (a,b), Point::new(state.x+a,state.y+b), Point::new(10,20));
let p = offset(1,2);
assert_eq!(p.x,11);
assert_eq!(p.y,22);

ClosureRef

This structure works like the above, but it does not own its state.

This struct is created by a macro closure_ref!.

Example:

let state = 10;
let add_ten:ClosureRef<i32,(i32,),i32> = closure_ref!(state, i, i+10, &state);
assert_eq!(add_ten(1),11);
let state = Point::new(10,20);
let offset:ClosureRef<Point,(i32,i32),Point>
    = closure_ref!(state, (a,b), Point::new(state.x+a,state.y+b), &state);
let p = offset(1,2);
assert_eq!(p.x,11);
assert_eq!(p.y,22);

ClosureMut

This struct works for closures that will mutate its state, but would not drop its state when called. So it can be called multiple times, but will have different effects on each call. Because it still owns its state, the state will be dropped when the struct was dropped.

This struct is created by a macro closure_mut!.

Example:

let mut accumulate:ClosureMut<i32,(i32,),i32> = closure_mut!(state, c, {*state+=c;*state}, 0);
assert_eq!(accumulate(1),1);
assert_eq!(accumulate(2),3);

ClosureRefMut

This struct works like the above, but it does not own its state. Furethermore, this is the only struct in this serial that does not support Copy and Clone at all, because it owns a mutable reference to its state.

This struct is created by a macro closure_ref_mut!.

Example:

let mut state = 0;
{
  let mut match_cnt:ClosureRefMut<i32,(i32,i32),()>
     = closure_ref_mut!(state, (a,b), {if a==b { *state+=1 }}, &mut state);
  for i in 0..10 { match_cnt(i,i*3%10); } //two matches: 0 and 5
}
assert_eq!(state,2);

ClosureOnce

This struct owns its state, and will drop its state when called.

This struct is created by macros closure_once! and closure_mut!. The later is useful when the state variable should be declared with mut keyword.

Example:

let sign_on:ClosureOnce<Passwd,(String,),Result<(),io::Error>>
   = closure_once!(passwd, user, authenticate(user,passwd), Passwd::get_from_cache());
let auth:ClosureOnce<RoleSet,(String,Passwd),Result<(),io::Error>>
   = closure_once!(role_set, (user,passwd), check_user(role_set,user,passwd), RoleSet::from_config());
//Use closure_once_mut when the state should be declared with `mut` keyword
let send_data:ClosureOnce<MyStream,(&[u8],),Result<usize,io::Error>>
    = closure_once_mut!(stream, data, stream.write_all(data), MyStream::new());
let read_data:ClosureOnce<MyStream,(&mut [u8],usize),Result<(),io::Error>>
    = closure_once_mut!(stream, (buf,len), stream.read_exact_ex(buf, len), MyStream::new());

Re-exports

pub use closures::Closure;
pub use closures::ClosureMut;
pub use closures::ClosureOnce;
pub use closures::ClosureRef;
pub use closures::ClosureRefMut;

Modules

closures

Macros

closure

Create a nameable closure object with an immutable state

closure_mut

Create a nameable closure object with a mutable state

closure_once

Create a nameable closure object consumes a state when called

closure_once_mut

Create a nameable closure object consumes a mutable state when called

closure_ref

Create a nameable closure object refers to an immutable state

closure_ref_mut

Create a nameable closure object refer to a mutable state