widgetui/widget/
function_widget.rs1use crate::widget::{into_widget::IntoWidget, param::WidgetParam, Widget};
2
3use crate::states::States;
4
5use crate::WidgetFrame;
6use crate::WidgetResult;
7
8use std::cell::RefMut;
9use std::marker::PhantomData;
10
11use std::any::{Any, TypeId};
12use std::collections::HashMap;
13
14pub struct FunctionWidget<Input, F> {
16 f: F,
17 marker: PhantomData<fn() -> Input>,
18}
19
20macro_rules! impl_for_func {
21 ($($item:ident)*) => {
22 impl<Func, $($item),*> Widget for FunctionWidget<($($item,)*), Func>
23 where
24 for<'a, 'b> &'a mut Func:
25 FnMut( $($item),* ) -> WidgetResult +
26 FnMut( $(<$item as WidgetParam>::Item<'b>),* ) -> WidgetResult,
27 $($item: WidgetParam + 'static),*
28 {
29 #[inline]
30 #[allow(non_snake_case, unused_variables)]
31 fn call(&mut self, states: &mut States) -> WidgetResult {
32 #[allow(clippy::too_many_arguments)]
33 fn call_inner<$($item),*>(
34 mut f: impl FnMut($($item),*) -> WidgetResult,
35 $($item: $item,)*
36 ) -> WidgetResult {
37 f($($item),*)
38 }
39
40 $(
41 let $item = $item::retrieve(states);
42 )*
43
44 call_inner(&mut self.f, $($item),*)
45 }
46 }
47 };
48}
49
50impl_for_func! {}
51impl_for_func! { A }
52impl_for_func! { A B }
53impl_for_func! { A B C }
54impl_for_func! { A B C D }
55impl_for_func! { A B C D E }
56impl_for_func! { A B C D E F }
57impl_for_func! { A B C D E F G }
58impl_for_func! { A B C D E F G H }
59impl_for_func! { A B C D E F G H I }
60impl_for_func! { A B C D E F G H I J }
61impl_for_func! { A B C D E F G H I J K }
62impl_for_func! { A B C D E F G H I J K L }
63
64macro_rules! impl_into_widget {
65 ($($item:ident)*) => {
66 impl<Func, $($item),*> IntoWidget<($($item,)*), ()> for Func
67 where
68 for<'a, 'b> &'a mut Func:
69 FnMut( $($item),* ) -> WidgetResult +
70 FnMut( $(<$item as WidgetParam>::Item<'b>),* ) -> WidgetResult,
71 $($item: WidgetParam + 'static),*
72
73 {
74 type Widget = FunctionWidget<($($item,)*), Self>;
75 #[inline]
76 #[allow(non_snake_case, unused_variables)]
77 fn into_widget(self) -> Self::Widget {
78 FunctionWidget {
79 f: self,
80 marker: Default::default(),
81 }
82 }
83 }
84 };
85}
86
87impl_into_widget! {}
88impl_into_widget! { A }
89impl_into_widget! { A B }
90impl_into_widget! { A B C }
91impl_into_widget! { A B C D }
92impl_into_widget! { A B C D E }
93impl_into_widget! { A B C D E F }
94impl_into_widget! { A B C D E F G }
95impl_into_widget! { A B C D E F G H }
96impl_into_widget! { A B C D E F G H I }
97impl_into_widget! { A B C D E F G H I J }
98impl_into_widget! { A B C D E F G H I J K }
99impl_into_widget! { A B C D E F G H I J K L }