1use crate::{AnyView, View, extract::Extractor};
14use alloc::boxed::Box;
15use core::{any::type_name, fmt::Debug, marker::PhantomData};
16
17use crate::Environment;
18
19pub type ActionObject = BoxHandler<()>;
21
22pub trait Handler<T>: 'static {
26 fn handle(&mut self, env: &Environment) -> T;
32}
33
34impl<T> Debug for dyn Handler<T> {
35 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36 f.write_str(type_name::<Self>())
37 }
38}
39
40impl<T> Debug for dyn HandlerOnce<T> {
41 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
42 f.write_str(type_name::<Self>())
43 }
44}
45
46impl Handler<()> for () {
47 fn handle(&mut self, _env: &Environment) {}
48}
49
50impl HandlerOnce<()> for () {
51 fn handle(self, _env: &Environment) {}
52}
53
54pub trait HandlerOnce<T>: 'static {
59 fn handle(self, env: &Environment) -> T;
65}
66
67pub type BoxHandler<T> = Box<dyn Handler<T>>;
69
70impl<T: 'static> Handler<T> for BoxHandler<T> {
71 fn handle(&mut self, env: &Environment) -> T {
72 self.as_mut().handle(env)
73 }
74}
75
76pub type BoxHandlerOnce<T> = Box<dyn HandlerOnce<T>>;
78
79impl<T: 'static> HandlerOnce<T> for Box<dyn HandlerOnce<T>> {
80 fn handle(self, env: &Environment) -> T {
81 trait CallBoxHandlerOnce<T> {
82 fn call_box(self: Box<Self>, env: &Environment) -> T;
83 }
84
85 impl<T, H> CallBoxHandlerOnce<T> for H
86 where
87 H: HandlerOnce<T>,
88 {
89 fn call_box(self: Box<Self>, env: &Environment) -> T {
90 self.handle(env)
91 }
92 }
93
94 Box::call_box(self.into(), env)
95 }
96}
97
98pub trait HandlerFn<P, T>: 'static {
102 fn handle_inner(&mut self, env: &Environment) -> T;
104}
105
106pub trait HandlerFnWithState<P, T, S>: 'static {
110 fn handle_inner(&mut self, state: S, env: &Environment) -> T;
112}
113
114pub trait HandlerFnOnce<P, T>: 'static {
118 fn handle_inner(self, env: &Environment) -> T;
120}
121
122macro_rules! impl_handle_fn {
123 ($($ty:ident),*) => {
124 #[allow(unused_variables)]
125 #[allow(non_snake_case)]
126 impl<F, R, $($ty:Extractor,)*> HandlerFn<($($ty,)*),R> for F
127 where
128 F: FnMut($($ty,)*) -> R+ 'static,
129 {
130 fn handle_inner(&mut self, env: &Environment) -> R {
131
132 $(
133 let $ty:$ty=Extractor::extract(env).expect("failed to extract value from environment");
134 )*
135
136 self($($ty,)*)
137 }
138 }
139 };
140}
141
142macro_rules! impl_handle_fn_with_state {
143 ($($ty:ident),*) => {
144 #[allow(unused_variables)]
145 #[allow(non_snake_case)]
146 impl<F, S, R, $($ty:Extractor,)*> HandlerFnWithState<($($ty,)*),R,S> for F
147 where
148 F: FnMut(S,$($ty,)*) -> R+ 'static,
149 {
150 fn handle_inner(&mut self, state:S, env: &Environment) -> R {
151
152 $(
153 let $ty:$ty=Extractor::extract(env).expect("failed to extract value from environment");
154 )*
155
156 self(state,$($ty,)*)
157 }
158 }
159 };
160}
161
162tuples!(impl_handle_fn_with_state);
163
164tuples!(impl_handle_fn);
165
166macro_rules! impl_handle_fn_once {
167 ($($ty:ident),*) => {
168 #[allow(unused_variables)]
169 #[allow(non_snake_case)]
170 impl<F, R, $($ty:Extractor,)*> HandlerFnOnce<($($ty,)*),R> for F
171 where
172 F: FnOnce($($ty,)*) -> R+ 'static,
173 {
174 fn handle_inner(self, env: &Environment) -> R {
175
176 $(
177 let $ty:$ty=Extractor::extract(env).expect("failed to extract value from environment");
178 )*
179
180 self($($ty,)*)
181 }
182 }
183 };
184}
185
186tuples!(impl_handle_fn_once);
187
188macro_rules! into_handlers {
189 ($name:ident,$handler:ident,$handler_fn:ident) => {
190 #[derive(Debug, Clone)]
192 pub struct $name<H, P, T> {
193 h: H,
194 _marker: PhantomData<(P, T)>,
195 }
196
197 impl<H, P, T> $name<H, P, T>
198 where
199 H: $handler_fn<P, T>,
200 {
201 #[must_use]
203 pub const fn new(h: H) -> Self {
204 Self {
205 h,
206 _marker: PhantomData,
207 }
208 }
209 }
210 };
211}
212
213#[derive(Debug)]
215pub struct IntoHandlerWithState<H, P, T, S> {
216 h: H,
217 state: S,
218 _marker: PhantomData<(P, T, S)>,
219}
220
221impl<H, P, T, S> IntoHandlerWithState<H, P, T, S>
222where
223 H: HandlerFnWithState<P, T, S>,
224 S: 'static + Clone,
225{
226 #[must_use]
228 pub const fn new(h: H, state: S) -> Self {
229 Self {
230 h,
231 state,
232 _marker: PhantomData,
233 }
234 }
235}
236
237impl<H, P, T, S> Handler<T> for IntoHandlerWithState<H, P, T, S>
238where
239 H: HandlerFnWithState<P, T, S>,
240 S: 'static + Clone,
241 T: 'static,
242 P: 'static,
243{
244 fn handle(&mut self, env: &Environment) -> T {
245 self.h.handle_inner(self.state.clone(), env)
246 }
247}
248
249pub const fn into_handler_with_state<H, P, T, S>(h: H, state: S) -> IntoHandlerWithState<H, P, T, S>
251where
252 H: HandlerFnWithState<P, T, S>,
253 S: 'static + Clone,
254 T: 'static,
255 P: 'static,
256{
257 IntoHandlerWithState::new(h, state)
258}
259
260into_handlers!(IntoHandler, Handler, HandlerFn);
261
262impl<H, P, T> Handler<T> for IntoHandler<H, P, T>
263where
264 H: HandlerFn<P, T>,
265 P: 'static,
266 T: 'static,
267{
268 fn handle(&mut self, env: &Environment) -> T {
269 self.h.handle_inner(env)
270 }
271}
272
273impl<H, P, T> HandlerOnce<T> for IntoHandlerOnce<H, P, T>
274where
275 H: HandlerFnOnce<P, T>,
276 P: 'static,
277 T: 'static,
278{
279 fn handle(self, env: &Environment) -> T {
280 self.h.handle_inner(env)
281 }
282}
283
284into_handlers!(IntoHandlerOnce, HandlerOnce, HandlerFnOnce);
285
286pub const fn into_handler<H, P, T>(h: H) -> IntoHandler<H, P, T>
296where
297 P: 'static,
298 T: 'static,
299 H: HandlerFn<P, T>,
300{
301 IntoHandler::new(h)
302}
303
304pub const fn into_handler_once<H, P, T>(h: H) -> IntoHandlerOnce<H, P, T>
314where
315 H: HandlerFnOnce<P, T>,
316 P: 'static,
317 T: 'static,
318{
319 IntoHandlerOnce::new(h)
320}
321
322pub trait ViewBuilder: 'static {
327 type Output: View;
329 fn build(&self) -> Self::Output;
333}
334
335impl<V: View, F> ViewBuilder for F
336where
337 F: 'static + Fn() -> V,
338{
339 type Output = V;
340 fn build(&self) -> Self::Output {
341 (self)()
342 }
343}
344
345pub struct AnyViewBuilder<V = AnyView>(Box<dyn ViewBuilder<Output = V>>);
349
350impl<V: View> AnyViewBuilder<V> {
351 #[must_use]
355 pub fn new(handler: impl ViewBuilder<Output = V>) -> Self {
356 Self(Box::new(handler))
357 }
358
359 #[must_use]
363 pub fn build(&self) -> V {
364 ViewBuilder::build(&*self.0)
365 }
366
367 #[must_use]
369 pub fn erase(self) -> AnyViewBuilder<AnyView> {
370 AnyViewBuilder::new(move || {
371 let v = self.build();
372 AnyView::new(v)
373 })
374 }
375}
376
377impl<V> Debug for AnyViewBuilder<V> {
378 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
379 f.write_str("AnyViewBuilder")
380 }
381}