1use crate::*;
2use ::type_sets::{Contains, Members, SubsetOf};
3use futures::{future::BoxFuture, Future};
4use std::{
5 any::{type_name, Any, TypeId},
6 fmt::Debug,
7 marker::PhantomData,
8};
9
10#[macro_export]
16macro_rules! DynSender {
17 ($($tt:tt)*) => {
18 $crate::DynSender::<$crate::Set![$($tt)*]>
19 };
20}
21
22pub struct DynSender<A, W = ()> {
46 sender: BoxedSender<W>,
47 t: PhantomData<fn() -> A>,
48}
49
50impl<A, W> DynSender<A, W> {
51 pub fn new<S>(sender: S) -> Self
53 where
54 S: SendsProtocol + DynSends<With = W>,
55 A: SubsetOf<S::Protocol>,
56 {
57 Self::new_unchecked(sender)
58 }
59
60 pub fn new_unchecked<S>(sender: S) -> Self
63 where
64 S: DynSends<With = W>,
65 {
66 Self::from_boxed_unchecked(Box::new(sender))
67 }
68
69 pub fn transform<A2>(self) -> DynSender<A2, W>
71 where
72 A2: SubsetOf<A>,
73 {
74 DynSender::from_boxed_unchecked(self.sender)
75 }
76
77 pub fn try_transform<A2>(self) -> Result<DynSender<A2, W>, Self>
80 where
81 A2: Members,
82 W: 'static,
83 A: 'static,
84 {
85 if A2::members().iter().all(|t2| self.members().contains(t2)) {
86 Ok(DynSender::from_boxed_unchecked(self.sender))
87 } else {
88 Err(self)
89 }
90 }
91
92 pub fn transform_unchecked<A2>(self) -> DynSender<A2, W> {
95 DynSender::from_boxed_unchecked(self.sender)
96 }
97
98 pub fn from_boxed_unchecked(sender: BoxedSender<W>) -> Self {
101 Self {
102 sender,
103 t: PhantomData,
104 }
105 }
106
107 pub fn into_boxed_sender(self) -> BoxedSender<W> {
109 self.sender
110 }
111
112 pub fn downcast_ref<S>(&self) -> Option<&S>
114 where
115 S: IsSender<With = W> + 'static,
116 W: 'static,
117 {
118 self.sender.as_any().downcast_ref::<S>()
119 }
120}
121
122impl<A, W> IsSender for DynSender<A, W> {
123 type With = W;
124
125 fn is_closed(&self) -> bool {
126 self.sender.is_closed()
127 }
128
129 fn capacity(&self) -> Option<usize> {
130 self.sender.capacity()
131 }
132
133 fn len(&self) -> usize {
134 self.sender.len()
135 }
136
137 fn receiver_count(&self) -> usize {
138 self.sender.receiver_count()
139 }
140
141 fn sender_count(&self) -> usize {
142 self.sender.sender_count()
143 }
144}
145
146impl<A, W> DynSends for DynSender<A, W>
147where
148 A: 'static,
149 W: 'static,
150{
151 fn dyn_send_boxed_msg_with(
152 &self,
153 msg: BoxedMsg<Self::With>,
154 ) -> BoxFuture<Result<(), DynSendError<BoxedMsg<Self::With>>>> {
155 self.sender.dyn_send_boxed_msg_with(msg)
156 }
157
158 fn dyn_send_boxed_msg_blocking_with(
159 &self,
160 msg: BoxedMsg<Self::With>,
161 ) -> Result<(), DynSendError<BoxedMsg<Self::With>>> {
162 self.sender.dyn_send_boxed_msg_blocking_with(msg)
163 }
164
165 fn dyn_try_send_boxed_msg_with(
166 &self,
167 msg: BoxedMsg<Self::With>,
168 ) -> Result<(), DynTrySendError<BoxedMsg<Self::With>>> {
169 self.sender.dyn_try_send_boxed_msg_with(msg)
170 }
171
172 fn members(&self) -> &'static [TypeId] {
173 self.sender.members()
174 }
175
176 fn clone_boxed(&self) -> BoxedSender<Self::With> {
177 self.sender.clone_boxed()
178 }
179
180 fn as_any(&self) -> &dyn Any {
181 self.sender.as_any()
182 }
183}
184
185impl<A, W, M> Sends<M> for DynSender<A, W>
186where
187 A: Contains<M>,
188 M: Send + 'static,
189 W: Send + 'static,
190{
191 fn send_msg_with(
192 this: &Self,
193 msg: M,
194 with: Self::With,
195 ) -> impl Future<Output = Result<(), SendError<(M, Self::With)>>> + Send {
196 let fut = this.sender.dyn_send_msg_with(msg, with);
197 async {
198 match fut.await {
199 Ok(()) => Ok(()),
200 Err(e) => Err(match e {
201 DynSendError::NotAccepted(_e) => {
202 panic!("Message not accepted: {}", type_name::<(M, Self::With)>())
203 }
204 DynSendError::Closed((msg, with)) => SendError((msg, with)),
205 }),
206 }
207 }
208 }
209
210 fn try_send_msg_with(
211 this: &Self,
212 msg: M,
213 with: Self::With,
214 ) -> Result<(), TrySendError<(M, Self::With)>> {
215 match this.sender.dyn_try_send_msg_with(msg, with) {
216 Ok(()) => Ok(()),
217 Err(e) => Err(match e {
218 DynTrySendError::NotAccepted(_e) => {
219 panic!("Message not accepted: {}", type_name::<(M, Self::With)>())
220 }
221 DynTrySendError::Closed((msg, with)) => TrySendError::Closed((msg, with)),
222 DynTrySendError::Full((msg, with)) => TrySendError::Full((msg, with)),
223 }),
224 }
225 }
226}
227
228impl<A, W: Debug> Debug for DynSender<A, W> {
229 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
230 f.debug_struct("DynSender")
231 .field("sender", &"...")
232 .field("t", &type_name::<A>())
233 .finish()
234 }
235}
236
237impl<A, W: 'static> Clone for DynSender<A, W> {
238 fn clone(&self) -> Self {
239 Self {
240 sender: self.sender.clone(),
241 t: PhantomData,
242 }
243 }
244}