dyn_fn_once/lib.rs
1//! Provides dynamically-typed self-consuming closures, [DynFnOnce] and [DynFnOnceSend].
2//!
3//! E.g.
4//! ```
5//! use std::fmt::Write;
6//! use dyn_fn_once::DynFnOnce;
7//!
8//! /// Creates a closure which either multiplies or adds two numbers, and stores the result
9//! /// in `target`, returning the given string with the result appended.
10//! fn create_binary_operation<'capture>(
11//! target: &'capture mut u32,
12//! mut units: String,
13//! mul: bool
14//! ) -> DynFnOnce<'capture, (u32, u32), String> {
15//! if mul {
16//! let statically_typed_closure = move |a, b| {
17//! let product = a * b;
18//! units.write_fmt(format_args!(" = {product}")).unwrap();
19//! *target = product;
20//! units
21//! };
22//!
23//! // N.B. the closure takes multiple arguments, so we have to turn them
24//! // into a single tuple-typed argument
25//! DynFnOnce::from(|(a, b)| statically_typed_closure(a, b))
26//! } else {
27//! let statically_typed_closure = move |a, b| {
28//! let sum = a + b;
29//! units.write_fmt(format_args!(" = {sum}")).unwrap();
30//! *target = sum;
31//! units
32//! };
33//!
34//! // N.B. the closure takes multiple arguments, so we have to turn them
35//! // into a single tuple-typed argument
36//! DynFnOnce::from(|(a, b)| statically_typed_closure(a, b))
37//! }
38//! }
39//!
40//! let mut target: u32 = 0;
41//!
42//! assert_eq!(
43//! create_binary_operation(&mut target, String::from("Hertz"), true).call((3, 4)),
44//! String::from("Hertz = 12")
45//! );
46//! assert_eq!(target, 12);
47//!
48//! assert_eq!(
49//! create_binary_operation(&mut target, String::from("Watts"), false).call((3, 4)),
50//! String::from("Watts = 7")
51//! );
52//! assert_eq!(target, 7);
53//!
54//! ```
55mod dyn_fn_once;
56pub use dyn_fn_once::DynFnOnce;
57
58mod dyn_fn_once_send;
59pub use dyn_fn_once_send::DynFnOnceSend;