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;