widgetui/widget/
function_widget.rs

1use 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
14// A widget that comes from specifically a function.
15pub 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 }