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}