Crate serde_closure[][src]

Serializable closures.

Crates.ioRepo

This library provides macros to wrap closures such that they can be serialized and sent between other processes running the same binary.

fn sum_of_squares(input: &[i32]) -> i32 {
    input.dist_iter()
        .map(Fn!(|&i| i * i))
        .sum()
}

For example, if you have multiple forks of a process, or the same binary running on each of a cluster of machines, this library would help you to send closures between them.

This library aims to work in as simple and un-magical a way as possible. It currently requires nightly Rust for the unboxed_closures and fn_traits features (rust issue #29625).

  • There are three macros, FnOnce, FnMut and Fn, corresponding to the three types of Rust closure.
  • The captured variables, i.e. those variables that are referenced by the closure but are declared outside of it, must be explicitly listed.
  • There are currently some minor limitations of syntax over normal closure syntax, which are documented below.
  • The closure is coerced to a function pointer, which is wrapped by relative::Code such that it can safely be sent between processes.

Examples of wrapped closures

Inferred, non-capturing closure:

|a| a+1
FnMut!(|a| a+1)

Annotated, non-capturing closure:

|a: String| -> String { a.to_uppercase() }
FnMut!(|a: String| -> String { a.to_uppercase() })

Inferred closure, capturing num:

let mut num = 0;
|a| num += a
let mut num = 0;
FnMut!([num] |a| *num += a)

Note: As this is a FnMut closure, num is a mutable reference, and must be dereferenced to use.

move closure, capturing hello and world:

let hello = String::from("hello");
let mut world = String::new();
move |name| {
    world += (hello.to_uppercase() + name).as_str();
}
let hello = String::from("hello");
let mut world = String::new();
FnMut!([hello, world] move |name| {
    *world += (hello.to_uppercase() + name).as_str();
})

Note: world must be dereferenced to use.

Cosmetic limitations

As visible above, there are currently some minor limitations:

  • The captured variables in FnMut and Fn closures are references, so need to be dereferenced;
  • Compiler errors are not as helpful as normal:
error[E0308]: mismatched types
...
   = note: expected type `for<..> fn(&'r mut (..), (..))`
              found type `[closure@<FnMut macros>:9:9: 10:44 my_var:_]`

means that my_var is a captured variable, but was not explicitly listed.

Macros

Fn

Macro that wraps a closure, evaluating to a Fn struct that implements std::ops::Fn, serde's Serialize and Deserialize, and various convenience traits.

FnMut

Macro that wraps a closure, evaluating to a FnMut struct that implements std::ops::FnMut, serde's Serialize and Deserialize, and various convenience traits.

FnOnce

Macro that wraps a closure, evaluating to a FnOnce struct that implements std::ops::FnOnce, serde's Serialize and Deserialize, and various convenience traits.

Structs

Fn

A struct representing a serializable closure, created by the Fn macro. Implements std::ops::Fn, serde's Serialize and Deserialize, and various convenience traits.

FnMut

A struct representing a serializable closure, created by the FnMut macro. Implements std::ops::FnMut, serde's Serialize and Deserialize, and various convenience traits.

FnOnce

A struct representing a serializable closure, created by the FnOnce macro. Implements std::ops::FnOnce, serde's Serialize and Deserialize, and various convenience traits.