1#![no_std]
2
3use core::ops;
7
8#[cfg(test)]
9extern crate std;
10
11pub mod fns;
12
13pub trait FnOnce<Args> {
15 type Output;
17
18 fn call_once(self, args: Args) -> Self::Output;
20}
21
22pub trait FnMut<Args> {
24 type Output;
26
27 fn call_mut(&mut self, args: Args) -> Self::Output;
29}
30
31pub trait Fn<Args> {
33 type Output;
35
36 fn call(&self, args: Args) -> Self::Output;
38}
39
40macro_rules! impl_fn_traits {
41 ($(($types:ident, $fields:tt),)*) => {
42 impl_fn_traits!(@ [] [] $($types $fields)*);
43 };
44 (@ [$($types:ident)*] [$($fields:tt)*]) => {
45 #[automatically_derived]
46 impl<$($types,)* F, U> FnOnce<($($types,)*)> for F
47 where
48 F: ops::FnOnce($($types,)*) -> U,
49 {
50 type Output = U;
51
52 fn call_once(self, args: ($($types,)*)) -> Self::Output {
53 self($(args.$fields,)*)
54 }
55 }
56
57 #[automatically_derived]
58 impl<$($types,)* F, U> FnMut<($($types,)*)> for F
59 where
60 F: ops::FnMut($($types,)*) -> U + ?Sized,
61 {
62 type Output = U;
63
64 fn call_mut(&mut self, args: ($($types,)*)) -> Self::Output {
65 self($(args.$fields,)*)
66 }
67 }
68
69 #[automatically_derived]
70 impl<$($types,)* F, U> Fn<($($types,)*)> for F
71 where
72 F: ops::Fn($($types,)*) -> U + ?Sized,
73 {
74 type Output = U;
75
76 fn call(&self, args: ($($types,)*)) -> Self::Output {
77 self($(args.$fields,)*)
78 }
79 }
80 };
81 (@ [$($acc_types:ident)*] [$($acc_fields:tt)*] $type_0:ident $field_0:tt $($types:ident $fields:tt)*) => {
82 impl_fn_traits!(@ [$($acc_types)*] [$($acc_fields)*]);
83 impl_fn_traits!(@ [$($acc_types)* $type_0] [$($acc_fields)* $field_0] $($types $fields)*);
84 };
85}
86
87impl_fn_traits![
88 (T0, 0),
89 (T1, 1),
90 (T2, 2),
91 (T3, 3),
92 (T4, 4),
93 (T5, 5),
94 (T6, 6),
95 (T7, 7),
96 (T8, 8),
97 (T9, 9),
98 (T10, 10),
99 (T11, 11),
100 (T12, 12),
101 (T13, 13),
102 (T14, 14),
103 (T15, 15),
104 (T16, 16),
105 (T17, 17),
106 (T18, 18),
107 (T19, 19),
108 (T20, 20),
109 (T21, 21),
110 (T22, 22),
111 (T23, 23),
112 (T24, 24),
113 (T25, 25),
114 (T26, 26),
115 (T27, 27),
116 (T28, 28),
117 (T29, 29),
118 (T30, 30),
119 (T31, 31),
120];
121
122#[cfg(test)]
123mod tests {
124 use super::{Fn, FnMut, FnOnce};
125 use std::string::String;
126 use std::vec::Vec;
127
128 #[test]
129 fn test_fn_once() {
130 fn as_fn_once<T, U>(f: impl FnOnce<T, Output = U>) -> impl FnOnce<T, Output = U> {
131 f
132 }
133
134 assert_eq!(as_fn_once(String::into_bytes).call_once((String::from("abc"),)), b"abc");
135 }
136
137 #[test]
138 fn test_fn_mut() {
139 fn as_fn_mut<T, U>(f: impl FnMut<T, Output = U>) -> impl FnMut<T, Output = U> {
140 f
141 }
142
143 let mut values = Vec::new();
144
145 as_fn_mut(|x| values.push(x)).call_mut((4,));
146
147 assert_eq!(values, [4]);
148 }
149
150 #[test]
151 fn test_fn() {
152 fn as_fn<T, U>(f: impl Fn<T, Output = U>) -> impl Fn<T, Output = U> {
153 f
154 }
155
156 let s = String::from("abc");
157
158 assert_eq!(as_fn(String::as_str).call((&s,)), "abc");
159 }
160}