simple_ref_fn/
lib.rs

1#![no_std]
2#![warn(
3    explicit_outlives_requirements,
4    macro_use_extern_crate,
5    meta_variable_misuse,
6    missing_abi,
7    missing_docs,
8    noop_method_call,
9    pointer_structural_match,
10    single_use_lifetimes,
11    trivial_casts,
12    trivial_numeric_casts,
13    // unsafe_code,
14    unsafe_op_in_unsafe_fn,
15    unused_crate_dependencies,
16    unused_extern_crates,
17    unused_import_braces,
18    unused_lifetimes,
19    unused_qualifications,
20    variant_size_differences,
21    clippy::cargo_common_metadata,
22    clippy::clone_on_ref_ptr,
23    clippy::cognitive_complexity,
24    clippy::create_dir,
25    clippy::dbg_macro,
26    clippy::debug_assert_with_mut_call,
27    clippy::empty_line_after_outer_attr,
28    clippy::fallible_impl_from,
29    clippy::filetype_is_file,
30    clippy::float_cmp_const,
31    clippy::get_unwrap,
32    clippy::if_then_some_else_none,
33    clippy::imprecise_flops,
34    clippy::let_underscore_must_use,
35    clippy::lossy_float_literal,
36    clippy::multiple_inherent_impl,
37    clippy::mutex_integer,
38    clippy::nonstandard_macro_braces,
39    clippy::panic_in_result_fn,
40    clippy::path_buf_push_overwrite,
41    clippy::pedantic,
42    clippy::print_stderr,
43    clippy::print_stdout,
44    clippy::rc_buffer,
45    clippy::rc_mutex,
46    clippy::rest_pat_in_fully_bound_structs,
47    clippy::string_lit_as_bytes,
48    clippy::string_to_string,
49    clippy::suboptimal_flops,
50    clippy::suspicious_operation_groupings,
51    clippy::todo,
52    clippy::trivial_regex,
53    clippy::unimplemented,
54    clippy::unnecessary_self_imports,
55    clippy::unneeded_field_pattern,
56    clippy::use_debug,
57    clippy::use_self,
58    clippy::useless_let_if_seq,
59    clippy::useless_transmute,
60    clippy::verbose_file_reads,
61    clippy::wildcard_dependencies
62)]
63#![allow(clippy::non_ascii_literal)]
64
65//! This crate provides type-erased function wrappers that behave like `&dyn Fn(T) -> R` and `&mut dyn FnMut(T) -> R`,
66//! but do not require compiler to generate virtual tables.
67//!
68//! The following wrapper types are provided:
69//!
70//! | Type                       | Behaves like                           | [`Send`] | [`Sync`] |
71//! | -------------------------- | -------------------------------------- | -------- | -------- |
72//! | [`RefFn<'a, T, R>`]        | [`&'a dyn Fn(T) -> R`]                 | No       | No       |
73//! | [`RefSyncFn<'a, T, R>`]    | [`&'a (dyn Fn(T) -> R + Sync)`]        | Yes      | Yes      |
74//! | [`RefFnMut<'a, T, R>`]     | [`&'a mut dyn FnMut(T) -> R`]          | No       | Yes      |
75//! | [`RefSendFnMut<'a, T, R>`] | [`&'a mut (dyn FnMut(T) -> R + Send)`] | Yes      | Yes      |
76//!
77//! [`RefFn<'a, T, R>`]: `RefFn`
78//! [`RefSyncFn<'a, T, R>`]: `RefSyncFn`
79//! [`RefFnMut<'a, T, R>`]: `RefFnMut`
80//! [`RefSendFnMut<'a, T, R>`]: `RefSendFnMut`
81//! [`&'a dyn Fn(T) -> R`]: `Fn`
82//! [`&'a (dyn Fn(T) -> R + Sync)`]: `Fn`
83//! [`&'a mut dyn FnMut(T) -> R`]: `FnMut`
84//! [`&'a mut (dyn FnMut(T) -> R + Send)`]: `FnMut`
85//!
86//! ## Examples
87//!
88//! ### Bind a function with a reference
89//!
90//! ```rust
91//! use simple_ref_fn::{RefFn, StaticRefFunction};
92//!
93//! // Define a static function.
94//!
95//! struct F;
96//!
97//! impl StaticRefFunction<'_, u32, u32> for F {
98//!     type Output = u32;
99//!
100//!     fn call(data: &u32, arg: u32) -> Self::Output {
101//!         data + arg
102//!     }
103//! }
104//!
105//! // Bind the function with a reference.
106//!
107//! let data = 2;
108//! let f: RefFn<u32, u32> = F::bind(&data); // Type-erasure.
109//!
110//! assert_eq!(f.call(3), 5);
111//! assert_eq!(f.call(5), 7);
112//! assert_eq!(f.call(7), 9);
113//! ```
114//!
115//! ### Erase the type of a closure
116//!
117//! ```rust
118//! use simple_ref_fn::RefFn;
119//!
120//! let data = 2_u32;
121//! let closure = |arg: u32| data + arg;
122//! let f: RefFn<u32, u32> = RefFn::from(&closure);  // Type-erasure.
123//!
124//! assert_eq!(f.call(3), 5);
125//! assert_eq!(f.call(5), 7);
126//! assert_eq!(f.call(7), 9);
127//! ```
128
129pub use self::ref_fn::RefFn;
130pub use self::ref_fn_mut::RefFnMut;
131pub use self::ref_send_fn_mut::RefSendFnMut;
132pub use self::ref_sync_fn::RefSyncFn;
133pub use self::static_ref_function::StaticRefFunction;
134pub use self::static_ref_mut_function::StaticRefMutFunction;
135
136mod ref_fn;
137mod ref_fn_mut;
138mod ref_send_fn_mut;
139mod ref_sync_fn;
140mod static_ref_function;
141mod static_ref_mut_function;