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
pub mod mail;
pub mod session;
pub mod tcp;

use model::controll::*;
use model::mail::*;
use tokio::net::TcpStream;
use tokio::prelude::*;

/** 
An object implementing this trait handles TCP connections in a `Future`.

The caller would ask the service to `handle()` the `TcpStream`, 
then poll the returned future or more likely `tokio::spawn()` it.

Here's a dead simple implementation that returns a completed future 
and doesn't do anything with the stream:

```
# extern crate samotop;
# extern crate tokio;
# use samotop;
# use samotop::service::*;
# use tokio::net::TcpStream;
# use tokio::prelude::*;
# use tokio::prelude::future::FutureResult;
#[derive(Clone, Debug)]
pub struct DeadService;

impl TcpService for DeadService {
    type Future = FutureResult<(), ()>;
    fn handle(self, _stream: TcpStream) -> Self::Future {
        future::ok(()) // or do something with the stream
    }
}
```

You can then use this `DeadService` in samotop:

```
# use samotop::service::tcp::DeadService;
let task = samotop::builder()
        .with(DeadService)
        .build_task();
```

The `SamotopService` implements this trait.
*/
pub trait TcpService {
    type Future: Future<Item = (), Error = ()>;
    fn handle(self, stream: TcpStream) -> Self::Future;
}

/**
The service which implements this trait has a name.
*/
pub trait NamedService {
    fn name(&self) -> String;
}

/**
A mail guard can be queried whether a recepient is accepted on on which address.
*/
pub trait MailGuard {
    type Future: Future<Item = AcceptRecipientResult>;
    fn accept(&self, request: AcceptRecipientRequest) -> Self::Future;
}

/**
A mail queue allows us to queue an e-mail. 
We start with an envelope. Then, depending on implementation, 
the `Mail` implementation receives the e-mail body.
Finally, the caller queues the mail by calling `Mail.queue()`.
*/
pub trait MailQueue {
    type Mail;
    type MailFuture: Future<Item = Option<Self::Mail>>;
    fn mail(&self, envelope: Envelope) -> Self::MailFuture;
}

/**
The final step of sending a mail is queueing it for delivery.
*/
pub trait Mail {
    fn queue(self) -> QueueResult;
}

/**
A session service handles the Samotop session
*/
pub trait SessionService {
    type Handler;
    fn start(&self, tls_conf: TlsControll) -> Self::Handler;
}