1use unsafe_cell::UnsafeRefCell;
2use error::ErrCode;
3use core::{IoContext, ThreadIoContext, FnOp, Upcast};
4use async::{Sender, NullReceiver, Operation, WrappedHandler, Handler};
5
6use std::sync::Arc;
7use std::marker::PhantomData;
8
9pub struct ArcHandler<T, F, R, E> {
11 data: Arc<T>,
12 handler: F,
13 _marker: PhantomData<(R, E)>,
14}
15
16impl<T, F, R, E> ArcHandler<T, F, R, E>
17 where T: Send + Sync + 'static,
18 F: FnOnce(Arc<T>, Result<R, E>) + Send + 'static,
19 R: Send + 'static,
20 E: Send + 'static,
21{
22 fn send(self, _: &IoContext, res: Result<R, E>) {
23 let ArcHandler { data, handler, _marker } = self;
24 handler(data, res)
25 }
26}
27
28impl<T, F, R, E> Handler<R, E> for ArcHandler<T, F, R, E>
29 where T: Send + Sync + 'static,
30 F: FnOnce(Arc<T>, Result<R, E>) + Send + 'static,
31 R: Send + 'static,
32 E: Send + 'static,
33{
34 type Output = ();
35
36 type Receiver = NullReceiver;
37
38 fn channel<G>(self, op: G) -> (Operation<R, E, G>, Self::Receiver)
39 where G: WrappedHandler<R, E> + Send + 'static,
40 {
41 (Box::new((self, op)), NullReceiver)
42 }
43
44 fn result(self, _: &IoContext, res: Result<R, E>) -> Self::Output {
45 let ArcHandler { data, handler, _marker } = self;
46 handler(data, res)
47 }
48}
49
50impl<T, F, R, E, G> Upcast<FnOp + Send> for (ArcHandler<T, F, R, E>, G)
51 where T: Send + Sync + 'static,
52 F: FnOnce(Arc<T>, Result<R, E>) + Send + 'static,
53 R: Send + 'static,
54 E: Send + 'static,
55 G: WrappedHandler<R, E> + Send + 'static,
56{
57 fn upcast(self: Box<Self>) -> Box<FnOp + Send> {
58 self
59 }
60}
61
62impl<T, F, R, E, G> Sender<R, E, G> for (ArcHandler<T, F, R, E>, G)
63 where T: Send + Sync + 'static,
64 F: FnOnce(Arc<T>, Result<R, E>) + Send + 'static,
65 R: Send + 'static,
66 E: Send + 'static,
67 G: WrappedHandler<R, E> + Send + 'static,
68{
69 fn send(self: Box<Self>, ctx: &IoContext, res: Result<R, E>) {
70 ctx.post(move|ctx| self.0.send(ctx, res))
71 }
72
73 fn as_self(&self) -> &G {
74 &self.1
75 }
76
77 fn as_mut_self(&mut self) -> &mut G {
78 &mut self.1
79 }
80}
81
82impl<T, F, R, E, G> FnOp for (ArcHandler<T, F, R, E>, G)
83 where T: Send + Sync + 'static,
84 F: FnOnce(Arc<T>, Result<R, E>) + Send + 'static,
85 R: Send + 'static,
86 E: Send + 'static,
87 G: WrappedHandler<R, E> + Send + 'static,
88{
89 fn call_op(self: Box<Self>, ctx: &IoContext, this: &mut ThreadIoContext, ec: ErrCode) {
90 let mut g = UnsafeRefCell::new(&self.1);
91 unsafe { g.as_mut() }.perform(ctx, this, ec, self)
92 }
93}
94
95pub fn wrap<T, F, R, E>(handler: F, data: &Arc<T>) -> ArcHandler<T, F, R, E> {
118 ArcHandler {
119 data: data.clone(),
120 handler: handler,
121 _marker: PhantomData,
122 }
123}