actix/address/
envelope.rs1use tokio::sync::oneshot::Sender;
2
3use crate::{
4 actor::{Actor, AsyncContext},
5 context::Context,
6 handler::{Handler, Message, MessageResponse},
7};
8
9pub trait ToEnvelope<A, M: Message>
11where
12 A: Actor + Handler<M>,
13 A::Context: ToEnvelope<A, M>,
14{
15 fn pack(msg: M, tx: Option<Sender<M::Result>>) -> Envelope<A>;
17}
18
19pub trait EnvelopeProxy<A: Actor> {
20 fn handle(&mut self, act: &mut A, ctx: &mut A::Context);
22}
23
24impl<A, M> ToEnvelope<A, M> for Context<A>
25where
26 A: Actor<Context = Context<A>> + Handler<M>,
27 M: Message + Send + 'static,
28 M::Result: Send,
29{
30 fn pack(msg: M, tx: Option<Sender<M::Result>>) -> Envelope<A> {
31 Envelope::new(msg, tx)
32 }
33}
34
35pub struct Envelope<A: Actor>(Box<dyn EnvelopeProxy<A> + Send>);
36
37impl<A: Actor> Envelope<A> {
38 pub fn new<M>(msg: M, tx: Option<Sender<M::Result>>) -> Self
39 where
40 A: Handler<M>,
41 A::Context: AsyncContext<A>,
42 M: Message + Send + 'static,
43 M::Result: Send,
44 {
45 Envelope(Box::new(SyncEnvelopeProxy { tx, msg: Some(msg) }))
46 }
47
48 pub fn with_proxy(proxy: Box<dyn EnvelopeProxy<A> + Send>) -> Self {
49 Envelope(proxy)
50 }
51}
52
53impl<A: Actor> EnvelopeProxy<A> for Envelope<A> {
54 fn handle(&mut self, act: &mut A, ctx: &mut <A as Actor>::Context) {
55 self.0.handle(act, ctx)
56 }
57}
58
59pub struct SyncEnvelopeProxy<M>
60where
61 M: Message + Send,
62 M::Result: Send,
63{
64 msg: Option<M>,
65 tx: Option<Sender<M::Result>>,
66}
67
68impl<A, M> EnvelopeProxy<A> for SyncEnvelopeProxy<M>
69where
70 M: Message + Send + 'static,
71 M::Result: Send,
72 A: Actor + Handler<M>,
73 A::Context: AsyncContext<A>,
74{
75 fn handle(&mut self, act: &mut A, ctx: &mut <A as Actor>::Context) {
76 let tx = self.tx.take();
77 if tx.is_some() && tx.as_ref().unwrap().is_closed() {
78 return;
79 }
80
81 if let Some(msg) = self.msg.take() {
82 let fut = <A as Handler<M>>::handle(act, msg, ctx);
83 fut.handle(ctx, tx)
84 }
85 }
86}