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
use actor::Actor;
use fut::ActorFuture;
use message::Response;
use context::Context;
use address::SyncAddress;

/// Message response type
pub trait ResponseType {

    /// The type of value that this message will resolved with if it is successful.
    type Item;

    /// The type of error that this message will resolve with if it fails in a normal fashion.
    type Error;
}

impl<I, E> ResponseType for Result<I, E> where I: ResponseType {
    type Item = <I as ResponseType>::Item;
    type Error = ();
}

pub type MessageResult<M: ResponseType> = Result<M::Item, M::Error>;

pub trait IntoResponse<A: Actor, M: ResponseType> {
    fn into_response(self) -> Response<A, M>;
}

impl<A, M> IntoResponse<A, M> for ()
    where A: Actor + Handler<M>, M: ResponseType<Item=(), Error=()>,
{
    fn into_response(self) -> Response<A, M> {
        Response::reply(Ok(()))
    }
}

impl<A, M> IntoResponse<A, M> for Response<A, M>
    where A: Actor + Handler<M>, M: ResponseType,
{
    fn into_response(self) -> Response<A, M> {
        self
    }
}

impl<A, M> IntoResponse<A, M> for Result<M::Item, M::Error>
    where A: Actor + Handler<M>, M: ResponseType,
{
    fn into_response(self) -> Response<A, M> {
        self.into()
    }
}

impl<A, M, B> IntoResponse<A, M> for SyncAddress<B>
    where A: Actor + Handler<M>, M: ResponseType<Item=SyncAddress<B>, Error=()>,
          B: Actor<Context=Context<B>>
{
    fn into_response(self) -> Response<A, M> {
        Response::reply(Ok(self))
    }
}

pub type ResponseFuture<A: Actor, M: ResponseType> =
    Box<ActorFuture<Item=M::Item, Error=M::Error, Actor=A>>;

impl<A, M> IntoResponse<A, M> for Box<ActorFuture<Item=M::Item, Error=M::Error, Actor=A>>
    where A: Actor + Handler<M>, M: ResponseType
{
    fn into_response(self) -> Response<A, M> {
        self.into()
    }
}

/// Message handler
///
/// `Handler` implementation is a general way how to handle
/// incoming messages, streams, futures.
///
/// `M` is a message which can be handled by the actor.
#[allow(unused_variables)]
pub trait Handler<M> where Self: Actor, M: ResponseType
{
    type Result: IntoResponse<Self, M>;

    /// Method is called for every message received by this Actor
    fn handle(&mut self, msg: M, ctx: &mut Self::Context) -> Self::Result;
}