wheel_timer2/
callback.rs

1use std::any::Any;
2use std::marker::PhantomData;
3
4use crate::behave::Behave;
5
6pub type BoxedCallback = Box<dyn Callback<Box<dyn Any + Send>> + Send>;
7
8pub trait Callback<Ctx> {
9    fn call(&self, context: &mut Ctx) -> Behave;
10
11    fn boxed(self) -> BoxedCallback
12    where
13        Self: Sized,
14    {
15        unimplemented!()
16    }
17}
18
19impl<F, B> Callback<()> for F
20where
21    F: Fn() -> B + Send + 'static,
22    B: Into<Behave>,
23{
24    fn call(&self, _: &mut ()) -> Behave {
25        self().into()
26    }
27
28    fn boxed(self) -> BoxedCallback {
29        struct A<CB>(CB);
30
31        impl<CB> Callback<Box<dyn Any + Send>> for A<CB>
32        where
33            CB: Callback<()> + Send + 'static,
34        {
35            fn call(&self, _: &mut Box<dyn Any + Send>) -> Behave {
36                self.0.call(&mut ())
37            }
38        }
39
40        Box::new(A(self))
41    }
42}
43
44impl<F, B, C> Callback<(C,)> for F
45where
46    F: Fn(&mut C) -> B + Send + 'static,
47    B: Into<Behave>,
48    C: Send + 'static,
49{
50    fn call(&self, (ref mut ctx,): &mut (C,)) -> Behave {
51        self(ctx).into()
52    }
53
54    fn boxed(self) -> BoxedCallback {
55        struct A<C, CB>(CB, PhantomData<C>);
56
57        impl<C, CB> Callback<Box<dyn Any + Send>> for A<C, CB>
58        where
59            CB: Callback<(C,)> + Send + 'static,
60            C: Send + 'static,
61        {
62            fn call(&self, a: &mut Box<dyn Any + Send>) -> Behave {
63                self.0
64                    .call(unsafe { &mut *(a.downcast_mut::<C>().unwrap() as *mut C as *mut (C,)) })
65            }
66        }
67
68        Box::new(A::<C, _>(self, PhantomData::default()))
69    }
70}