1use std::rc::Rc;
2
3pub trait DynFn: FnOfArgs<Self::ArgsTuple, DynFn = Self> {
4 type ArgsTuple;
5}
6
7pub trait DynFnMut: FnMutOfArgs<Self::ArgsTuple, DynFnMut = Self> {
8 type ArgsTuple;
9}
10
11pub trait DynFnOnce: FnOnceOfArgs<Self::ArgsTuple, DynFnOnce = Self> {
12 type ArgsTuple;
13}
14
15pub trait FnOfArgs<TArgs>: FnMutOfArgs<TArgs> {
16 type DynFn: ?Sized + DynFn<ArgsTuple = TArgs>;
17
18 fn into_rc_dyn_fn(self: Rc<Self>) -> Rc<Self::DynFn>
19 where
20 Self: 'static;
21 fn rc_into_box_dyn_fn(self: Rc<Self>) -> Box<Self::DynFn>
22 where
23 Self: 'static;
24 fn into_box_dyn_fn(self: Box<Self>) -> Box<Self::DynFn>
25 where
26 Self: 'static;
27}
28
29pub trait FnMutOfArgs<TArgs>: FnOnceOfArgs<TArgs> {
30 type DynFnMut: ?Sized + DynFnMut<ArgsTuple = TArgs>;
31
32 fn into_box_dyn_fn_mut(self: Box<Self>) -> Box<Self::DynFnMut>
33 where
34 Self: 'static;
35}
36
37pub trait FnOnceOfArgs<TArgs> {
38 type Output;
39 type DynFnOnce: ?Sized + DynFnOnce<ArgsTuple = TArgs>;
40
41 fn into_box_dyn_fn_once(self: Box<Self>) -> Box<Self::DynFnOnce>
42 where
43 Self: 'static;
44}
45
46macro_rules! doit {
47 ($(
48 ($($var:ident)*)
49 )*) => ($(
50 impl<$($var,)* TReturn> DynFn for dyn Fn($($var,)*) -> TReturn {
51 type ArgsTuple = ($($var,)*);
52 }
53
54 impl<$($var,)* TReturn> DynFnMut for dyn FnMut($($var,)*) -> TReturn {
55 type ArgsTuple = ($($var,)*);
56 }
57
58 impl<$($var,)* TReturn> DynFnOnce for dyn FnOnce($($var,)*) -> TReturn {
59 type ArgsTuple = ($($var,)*);
60 }
61
62 impl<TFunc, $($var,)* TReturn> FnOnceOfArgs<($($var,)*)> for TFunc
63 where TFunc: FnOnce($($var),*) -> TReturn
64 {
65 type Output = TReturn;
66 type DynFnOnce = dyn FnOnce($($var,)*) -> TReturn;
67
68 #[inline]
69 fn into_box_dyn_fn_once(self: Box<Self>) -> Box<Self::DynFnOnce>
70 where
71 Self: 'static,
72 {
73 self as Box<Self::DynFnOnce>
74 }
75 }
76
77 impl<$($var,)* TReturn> FnOnceOfArgs<($($var,)*)> for dyn FnOnce($($var),*) -> TReturn {
78 type Output = TReturn;
79 type DynFnOnce = Self;
80
81 #[inline]
82 fn into_box_dyn_fn_once(self: Box<Self>) -> Box<Self::DynFnOnce>
83 where
84 Self: 'static,
85 {
86 self
87 }
88 }
89
90 impl<$($var,)* TReturn> FnOnceOfArgs<($($var,)*)> for dyn FnMut($($var),*) -> TReturn {
91 type Output = TReturn;
92 type DynFnOnce = dyn FnOnce($($var,)*) -> TReturn;
93
94 #[inline]
95 fn into_box_dyn_fn_once(self: Box<Self>) -> Box<Self::DynFnOnce>
96 where
97 Self: 'static,
98 {
99 Box::new(self) as Box<Self::DynFnOnce>
100 }
101 }
102
103 impl<$($var,)* TReturn> FnOnceOfArgs<($($var,)*)> for dyn Fn($($var),*) -> TReturn {
104 type Output = TReturn;
105 type DynFnOnce = dyn FnOnce($($var,)*) -> TReturn;
106
107 #[inline]
108 fn into_box_dyn_fn_once(self: Box<Self>) -> Box<Self::DynFnOnce>
109 where
110 Self: 'static,
111 {
112 Box::new(self) as Box<Self::DynFnOnce>
113 }
114 }
115
116 impl<TFunc, $($var,)* TReturn> FnMutOfArgs<($($var,)*)> for TFunc
117 where TFunc: FnMut($($var),*) -> TReturn
118 {
119 type DynFnMut = dyn FnMut($($var,)*) -> TReturn;
120
121 #[inline]
122 fn into_box_dyn_fn_mut(self: Box<Self>) -> Box<Self::DynFnMut>
123 where
124 Self: 'static,
125 {
126 self as Box<Self::DynFnMut>
127 }
128 }
129
130 impl<$($var,)* TReturn> FnMutOfArgs<($($var,)*)> for dyn FnMut($($var),*) -> TReturn {
131 type DynFnMut = Self;
132
133 #[inline]
134 fn into_box_dyn_fn_mut(self: Box<Self>) -> Box<Self::DynFnMut>
135 where
136 Self: 'static,
137 {
138 self
139 }
140 }
141
142 impl<$($var,)* TReturn> FnMutOfArgs<($($var,)*)> for dyn Fn($($var),*) -> TReturn {
143 type DynFnMut = dyn FnMut($($var,)*) -> TReturn;
144
145 #[inline]
146 fn into_box_dyn_fn_mut(self: Box<Self>) -> Box<Self::DynFnMut>
147 where
148 Self: 'static,
149 {
150 Box::new(self) as Box<Self::DynFnMut>
151 }
152 }
153
154 impl<TFunc, $($var,)* TReturn> FnOfArgs<($($var,)*)> for TFunc
155 where TFunc: Fn($($var),*) -> TReturn
156 {
157 type DynFn = dyn Fn($($var,)*) -> TReturn;
158
159 #[inline]
160 fn into_rc_dyn_fn(self: Rc<Self>) -> Rc<Self::DynFn>
161 where
162 Self: 'static,
163 {
164 self as Rc<Self::DynFn>
165 }
166
167 #[inline]
168 fn rc_into_box_dyn_fn(self: Rc<Self>) -> Box<Self::DynFn>
169 where
170 Self: 'static,
171 {
172 #![allow(non_snake_case)]
173 Box::new(move |$($var: $var),*| (*self)($($var),*)) as Box<Self::DynFn>
174 }
175
176 #[inline]
177 fn into_box_dyn_fn(self: Box<Self>) -> Box<Self::DynFn>
178 where
179 Self: 'static,
180 {
181 self as Box<Self::DynFn>
182 }
183 }
184
185 impl<$($var,)* TReturn> FnOfArgs<($($var,)*)> for dyn Fn($($var),*) -> TReturn {
186 type DynFn = Self;
187
188 #[inline]
189 fn into_rc_dyn_fn(self: Rc<Self>) -> Rc<Self::DynFn>
190 where
191 Self: 'static,
192 {
193 self as Rc<Self::DynFn>
194 }
195
196 #[inline]
197 fn rc_into_box_dyn_fn(self: Rc<Self>) -> Box<Self::DynFn>
198 where
199 Self: 'static,
200 {
201 #![allow(non_snake_case)]
202 Box::new(move |$($var: $var),*| (*self)($($var),*)) as Box<Self::DynFn>
203 }
204
205 #[inline]
206 fn into_box_dyn_fn(self: Box<Self>) -> Box<Self::DynFn>
207 where
208 Self: 'static,
209 {
210 self as Box<Self::DynFn>
211 }
212 }
213
214 impl<TFunc: 'static + Fn($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<$crate::AnyFn<dyn Fn($($var,)*) -> TReturn>> for TFunc {
215 #[inline]
216 fn into_prop_value(self) -> $crate::AnyFn<dyn Fn($($var,)*) -> TReturn> {
217 $crate::AnyFn::new(self)
218 }
219 }
220
221 impl<TFunc: 'static + Fn($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<Option<$crate::AnyFn<dyn Fn($($var,)*) -> TReturn>>> for TFunc {
222 #[inline]
223 fn into_prop_value(self) -> Option<$crate::AnyFn<dyn Fn($($var,)*) -> TReturn>> {
224 Some($crate::AnyFn::new(self))
225 }
226 }
227
228 impl<TFunc: 'static + Fn($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<Option<$crate::AnyFn<dyn Fn($($var,)*) -> TReturn>>> for Option<TFunc> {
229 #[inline]
230 fn into_prop_value(self) -> Option<$crate::AnyFn<dyn Fn($($var,)*) -> TReturn>> {
231 self.map($crate::IntoPropValue::into_prop_value)
232 }
233 }
234
235 impl<TFunc: 'static + FnMut($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<$crate::AnyFnMut<dyn FnMut($($var,)*) -> TReturn>> for TFunc {
236 #[inline]
237 fn into_prop_value(self) -> $crate::AnyFnMut<dyn FnMut($($var,)*) -> TReturn> {
238 $crate::AnyFnMut::new(self)
239 }
240 }
241
242 impl<TFunc: 'static + FnMut($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<Option<$crate::AnyFnMut<dyn FnMut($($var,)*) -> TReturn>>> for TFunc {
243 #[inline]
244 fn into_prop_value(self) -> Option<$crate::AnyFnMut<dyn FnMut($($var,)*) -> TReturn>> {
245 Some($crate::AnyFnMut::new(self))
246 }
247 }
248
249 impl<TFunc: 'static + FnMut($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<Option<$crate::AnyFnMut<dyn FnMut($($var,)*) -> TReturn>>> for Option<TFunc> {
250 #[inline]
251 fn into_prop_value(self) -> Option<$crate::AnyFnMut<dyn FnMut($($var,)*) -> TReturn>> {
252 self.map($crate::IntoPropValue::into_prop_value)
253 }
254 }
255
256 impl<TFunc: 'static + FnOnce($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<$crate::AnyFnOnce<dyn FnOnce($($var,)*) -> TReturn>> for TFunc {
257 #[inline]
258 fn into_prop_value(self) -> $crate::AnyFnOnce<dyn FnOnce($($var,)*) -> TReturn> {
259 $crate::AnyFnOnce::new(self)
260 }
261 }
262
263 impl<TFunc: 'static + FnOnce($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<Option<$crate::AnyFnOnce<dyn FnOnce($($var,)*) -> TReturn>>> for TFunc {
264 #[inline]
265 fn into_prop_value(self) -> Option<$crate::AnyFnOnce<dyn FnOnce($($var,)*) -> TReturn>> {
266 Some($crate::AnyFnOnce::new(self))
267 }
268 }
269
270 impl<TFunc: 'static + FnOnce($($var,)*) -> TReturn, TReturn, $($var,)*> $crate::IntoPropValue<Option<$crate::AnyFnOnce<dyn FnOnce($($var,)*) -> TReturn>>> for Option<TFunc> {
271 #[inline]
272 fn into_prop_value(self) -> Option<$crate::AnyFnOnce<dyn FnOnce($($var,)*) -> TReturn>> {
273 self.map($crate::IntoPropValue::into_prop_value)
274 }
275 }
276 )*)
277}
278
279doit! {
280 ()
281 (A)
282 (A B)
283 (A B C)
284 (A B C D)
285 (A B C D E)
286 (A B C D E F)
287 (A B C D E F G)
288 (A B C D E F G H)
289}