1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use dyn_clone::DynClone;

use crate::{ActorId, Message, Result};
use std::future::Future;
use std::hash::{Hash, Hasher};
use std::pin::Pin;

pub(crate) trait CallerFn<T>: DynClone + Send + Sync + 'static
where
    T: Message,
{
    fn call(&self, msg: T) -> Pin<Box<dyn Future<Output = Result<T::Result>>>>;
}

impl<F, T> CallerFn<T> for F
where
    F: Fn(T) -> Pin<Box<dyn Future<Output = Result<T::Result>>>>,
    F: 'static + Send + Sync + DynClone,
    T: Message,
{
    fn call(&self, msg: T) -> Pin<Box<dyn Future<Output = Result<T::Result>>>> {
        self(msg)
    }
}

pub(crate) trait SenderFn<T>: DynClone + 'static + Send + Sync
where
    T: Message,
{
    fn send(&self, msg: T) -> Result<()>;
}

impl<F, T> SenderFn<T> for F
where
    F: Fn(T) -> Result<()>,
    F: 'static + Send + Sync + Clone,
    T: Message,
{
    fn send(&self, msg: T) -> Result<()> {
        self(msg)
    }
}

pub(crate) trait TestFn: DynClone + 'static + Send + Sync {
    fn test(&self) -> bool;
}

impl<F> TestFn for F
where
    F: Fn() -> bool,
    F: DynClone + 'static + Send + Sync,
{
    fn test(&self) -> bool {
        self()
    }
}

/// Caller of a specific message type
///
/// Like [`Sender<T>`], `Caller` has a weak reference to the recipient of the message type,
/// and so will not prevent an actor from stopping if all [`Addr`](`crate::Addr`)'s have been dropped elsewhere.

pub struct Caller<T: Message> {
    /// Id of the corresponding [`Actor<A>`](crate::Actor<A>)
    pub actor_id: ActorId,
    pub(crate) caller_fn: Box<dyn CallerFn<T>>,
    pub(crate) test_fn: Box<dyn TestFn>,
}

impl<T: Message> Caller<T> {
    pub async fn call(&self, msg: T) -> Result<T::Result> {
        self.caller_fn.call(msg).await
    }
    pub fn can_upgrade(&self) -> bool {
        self.test_fn.test()
    }
}

impl<T: Message<Result = ()>> PartialEq for Caller<T> {
    fn eq(&self, other: &Self) -> bool {
        self.actor_id == other.actor_id
    }
}

impl<T: Message<Result = ()>> Hash for Caller<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.actor_id.hash(state);
    }
}

impl<T: Message> Clone for Caller<T> {
    fn clone(&self) -> Self {
        Self {
            actor_id: self.actor_id,
            caller_fn: dyn_clone::clone_box(&*self.caller_fn),
            test_fn: dyn_clone::clone_box(&*self.test_fn),
        }
    }
}

/// Sender of a specific message type
///
/// Like [`Caller<T>`], Sender has a weak reference to the recipient of the message type,
/// and so will not prevent an actor from stopping if all [`Addr`](`crate::Addr`)'s have been dropped elsewhere.
/// This allows it to be used in the `send_later` and `send_interval` actor functions,
/// and not keep the actor alive indefinitely even after all references to it have been dropped (unless `ctx.stop()` is called from within)

pub struct Sender<T: Message> {
    /// Id of the corresponding [`Actor<A>`](crate::actor::Actor)
    pub actor_id: ActorId,
    pub(crate) sender_fn: Box<dyn SenderFn<T>>,
    pub(crate) test_fn: Box<dyn TestFn>,
}

impl<T: Message<Result = ()>> Sender<T> {
    pub fn send(&self, msg: T) -> Result<()> {
        self.sender_fn.send(msg)
    }
    pub fn can_upgrade(&self) -> bool {
        self.test_fn.test()
    }
}

impl<T: Message<Result = ()>> PartialEq for Sender<T> {
    fn eq(&self, other: &Self) -> bool {
        self.actor_id == other.actor_id
    }
}

impl<T: Message<Result = ()>> Hash for Sender<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.actor_id.hash(state);
    }
}