Crates.io | serde_closure |
lib.rs | serde_closure |
version | 0.3.3 |
source | src |
created_at | 2018-07-17 21:20:57.150262 |
updated_at | 2022-11-24 12:49:44.203314 |
description | Serializable and debuggable closures. This library provides macros that wrap closures to make them serializable and debuggable. |
homepage | https://github.com/alecmocatta/serde_closure |
repository | https://github.com/alecmocatta/serde_closure |
max_upload_size | |
id | 74789 |
size | 63,375 |
Serializable and debuggable closures.
This library provides macros that wrap closures to make them serializable and debuggable.
use serde_closure::{traits::Fn, Fn};
let one = 1;
let plus_one = Fn!(|x: i32| x + one);
assert_eq!(2, plus_one.call((1,))); // this works on stable and nightly
// assert_eq!(2, plus_one(1)); // this only works on nightly
println!("{:#?}", plus_one);
// prints:
// Fn<main::{{closure}} at main.rs:6:15> {
// one: 1,
// source: "| x : i32 | x + one",
// }
This library aims to work in as simple and safe a way as possible. On stable
Rust the wrapped closures implement
traits::FnOnce
,
traits::FnMut
and traits::Fn
,
and on nightly Rust
std::ops::FnOnce
,
std::ops::FnMut
and
std::ops::Fn
are
implemented as well using the unboxed_closures
and fn_traits
features (rust
issue #29625).
FnOnce
,
FnMut
and Fn
,
corresponding to the three types of Rust closure.Copy
,
Clone
, PartialEq
, Eq
, Hash
, PartialOrd
, Ord
, Serialize
,
Deserialize
and Debug
.unsafe
.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!(|a| num += a)
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!(move |name| {
world += (hello.to_uppercase() + name).as_str();
})
There are currently some minor limitations:
my_struct::<>
to disambiguate.error[E0308]: mismatched types
--> tests/test.rs:450:4
|
449 | FnOnce!(move || {
| _____-
450 | | my_struct;
| | ^^^^^^^^^ expected struct `serde_closure::internal::a_variable`, found struct `my_struct`
451 | | });
| |______- in this macro invocation
|
= note: expected type `serde_closure::internal::a_variable`
found type `my_struct`
(MyVariable)
to disambiguate.error: imports cannot refer to local variables
--> tests/test.rs:422:3
|
417 | FnOnce!(move || {
| _____-
418 | | MyVariable;
| | ^^^^^^^^^^
419 | | });
| |______- in this macro invocation
|
function::<>
for
functions and (closure)
for closures.Closures created by this crate are unnameable – i.e. just like normal closures, there is no Rust syntax available with which to write the type. What this means is that to deserialize a closure, you either need to specify the precise type you're deserializing without naming it (which is possible but not particularly practical), or erase the type by storing it in a trait object.
The serde_traitobject
crate enables trait objects to be safely serialized and sent between other
processes running the same binary.
For example, if you have multiple forks of a process, or the same binary running
on each of a cluster of machines,
serde_traitobject
would
help you to send serializable closures between them. This can be done by
upcasting the closure to a Box<dyn serde_traitobject::Fn()>
, which is
automatically serializable and deserializable with
serde
.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.