1use std::marker::PhantomData;
2use std::sync::Arc;
3
4use crate::core::futures::Future;
5use crate::core::{self, Metadata, Params, RemoteProcedure, RpcMethod, Value};
6use crate::handler::{SubscribeRpcMethod, UnsubscribeRpcMethod};
7use crate::subscription::{new_subscription, Subscriber};
8use crate::types::{PubSubMetadata, SubscriptionId};
9
10struct DelegateSubscription<T, F> {
11 delegate: Arc<T>,
12 closure: F,
13}
14
15impl<T, M, F> SubscribeRpcMethod<M> for DelegateSubscription<T, F>
16where
17 M: PubSubMetadata,
18 F: Fn(&T, Params, M, Subscriber),
19 T: Send + Sync + 'static,
20 F: Send + Sync + 'static,
21{
22 fn call(&self, params: Params, meta: M, subscriber: Subscriber) {
23 let closure = &self.closure;
24 closure(&self.delegate, params, meta, subscriber)
25 }
26}
27
28impl<M, T, F, I> UnsubscribeRpcMethod<M> for DelegateSubscription<T, F>
29where
30 M: PubSubMetadata,
31 F: Fn(&T, SubscriptionId, Option<M>) -> I,
32 I: Future<Output = core::Result<Value>> + Send + 'static,
33 T: Send + Sync + 'static,
34 F: Send + Sync + 'static,
35{
36 type Out = I;
37 fn call(&self, id: SubscriptionId, meta: Option<M>) -> Self::Out {
38 let closure = &self.closure;
39 closure(&self.delegate, id, meta)
40 }
41}
42
43pub struct IoDelegate<T, M = ()>
45where
46 T: Send + Sync + 'static,
47 M: Metadata,
48{
49 inner: core::IoDelegate<T, M>,
50 delegate: Arc<T>,
51 _data: PhantomData<M>,
52}
53
54impl<T, M> IoDelegate<T, M>
55where
56 T: Send + Sync + 'static,
57 M: PubSubMetadata,
58{
59 pub fn new(delegate: Arc<T>) -> Self {
61 IoDelegate {
62 inner: core::IoDelegate::new(delegate.clone()),
63 delegate,
64 _data: PhantomData,
65 }
66 }
67
68 pub fn add_subscription<Sub, Unsub, I>(&mut self, name: &str, subscribe: (&str, Sub), unsubscribe: (&str, Unsub))
70 where
71 Sub: Fn(&T, Params, M, Subscriber),
72 Sub: Send + Sync + 'static,
73 Unsub: Fn(&T, SubscriptionId, Option<M>) -> I,
74 I: Future<Output = core::Result<Value>> + Send + 'static,
75 Unsub: Send + Sync + 'static,
76 {
77 let (sub, unsub) = new_subscription(
78 name,
79 DelegateSubscription {
80 delegate: self.delegate.clone(),
81 closure: subscribe.1,
82 },
83 DelegateSubscription {
84 delegate: self.delegate.clone(),
85 closure: unsubscribe.1,
86 },
87 );
88 self.inner
89 .add_method_with_meta(subscribe.0, move |_, params, meta| sub.call(params, meta));
90 self.inner
91 .add_method_with_meta(unsubscribe.0, move |_, params, meta| unsub.call(params, meta));
92 }
93
94 pub fn add_alias(&mut self, from: &str, to: &str) {
96 self.inner.add_alias(from, to)
97 }
98
99 pub fn add_method<F, I>(&mut self, name: &str, method: F)
102 where
103 F: Fn(&T, Params) -> I,
104 I: Future<Output = core::Result<Value>> + Send + 'static,
105 F: Send + Sync + 'static,
106 {
107 self.inner.add_method(name, method)
108 }
109
110 pub fn add_method_with_meta<F, I>(&mut self, name: &str, method: F)
112 where
113 F: Fn(&T, Params, M) -> I,
114 I: Future<Output = core::Result<Value>> + Send + 'static,
115 F: Send + Sync + 'static,
116 {
117 self.inner.add_method_with_meta(name, method)
118 }
119
120 pub fn add_notification<F>(&mut self, name: &str, notification: F)
122 where
123 F: Fn(&T, Params),
124 F: Send + Sync + 'static,
125 {
126 self.inner.add_notification(name, notification)
127 }
128}
129
130impl<T, M> core::IoHandlerExtension<M> for IoDelegate<T, M>
131where
132 T: Send + Sync + 'static,
133 M: Metadata,
134{
135 fn augment<S: core::Middleware<M>>(self, handler: &mut core::MetaIoHandler<M, S>) {
136 handler.extend_with(self.inner)
137 }
138}
139
140impl<T, M> IntoIterator for IoDelegate<T, M>
141where
142 T: Send + Sync + 'static,
143 M: Metadata,
144{
145 type Item = (String, RemoteProcedure<M>);
146 type IntoIter = <core::IoDelegate<T, M> as IntoIterator>::IntoIter;
147
148 fn into_iter(self) -> Self::IntoIter {
149 self.inner.into_iter()
150 }
151}