simple_ref_fn/
ref_sync_fn.rs1use crate::ref_fn::RefFn;
2use crate::static_ref_function::StaticRefFunction;
3
4pub struct RefSyncFn<'a, T, R> {
7 inner: RefFn<'a, T, R>,
8}
9
10impl<'a, T, R> RefSyncFn<'a, T, R> {
11 pub fn new<F, D>(data: &'a D) -> Self
13 where
14 F: StaticRefFunction<'a, D, T, Output = R> + ?Sized,
15 D: Sync,
16 {
17 Self {
18 inner: RefFn::new::<F, D>(data),
19 }
20 }
21
22 pub fn from_fn<F>(f: &'a F) -> Self
24 where
25 F: Fn(T) -> R + Sync,
26 {
27 Self::new::<F, F>(f)
28 }
29
30 pub fn call(&self, arg: T) -> R {
32 self.inner.call(arg)
33 }
34}
35
36impl<T, R> Clone for RefSyncFn<'_, T, R> {
37 fn clone(&self) -> Self {
38 *self
39 }
40}
41
42impl<T, R> Copy for RefSyncFn<'_, T, R> {}
43
44impl<'a, F, T, R> From<&'a F> for RefSyncFn<'a, T, R>
45where
46 F: Fn(T) -> R + Sync,
47{
48 fn from(value: &'a F) -> Self {
49 Self::from_fn(value)
50 }
51}
52
53unsafe impl<T, R> Send for RefSyncFn<'_, T, R> {}
54unsafe impl<T, R> Sync for RefSyncFn<'_, T, R> {}
55
56#[cfg(test)]
57mod tests {
58 use super::RefSyncFn;
59 use crate::static_ref_function::StaticRefFunction;
60
61 static_assertions::assert_impl_all!(RefSyncFn<'static, (), ()>: Clone, Copy, From<&'static fn(())>, Send, Sync);
62
63 #[test]
64 fn test_ref_sync_fn_new() {
65 struct F;
66
67 impl StaticRefFunction<'_, u32, u32> for F {
68 type Output = u32;
69
70 fn call(data: &u32, arg: u32) -> Self::Output {
71 data + arg
72 }
73 }
74
75 let data = 2;
76 let f: RefSyncFn<u32, u32> = F::bind_sync(&data);
77
78 assert_eq!(f.call(3), 5);
79 assert_eq!(f.call(5), 7);
80 assert_eq!(f.call(7), 9);
81 }
82
83 #[test]
84 fn test_ref_sync_fn_from() {
85 let data = 2_u32;
86 let closure = |arg: u32| data + arg;
87 let f: RefSyncFn<u32, u32> = RefSyncFn::from(&closure);
88
89 assert_eq!(f.call(3), 5);
90 assert_eq!(f.call(5), 7);
91 assert_eq!(f.call(7), 9);
92 }
93}