samotop_core/mail/
service.rs1use crate::{
2 common::*,
3 io::{tls::MayBeTls, ConnectionInfo, IoService},
4 mail::{
5 AddRecipientResult, DispatchResult, MailDispatch, MailGuard, Recipient, StartMailResult,
6 },
7 smtp::{Drive, Interpret, SessionService, SmtpContext, SmtpSession},
8};
9
10pub trait MailService: SessionService + MailGuard + MailDispatch {}
12impl<T> MailService for T where T: SessionService + MailGuard + MailDispatch {}
13
14#[derive(Debug, Clone)]
19pub struct Service {
20 session: Arc<dyn SessionService + Sync + Send>,
21 guard: Arc<dyn MailGuard + Sync + Send>,
22 dispatch: Arc<dyn MailDispatch + Sync + Send>,
23 driver: Arc<dyn Drive + Sync + Send>,
24 interpret: Arc<dyn Interpret + Sync + Send>,
25}
26
27impl Service {
28 pub fn new<T, I, E, G, D>(drive: T, interpret: I, session: E, guard: G, dispatch: D) -> Self
30 where
31 T: Drive + Sync + Send + 'static,
32 I: Interpret + Sync + Send + 'static,
33 E: SessionService + Sync + Send + 'static,
34 G: MailGuard + Sync + Send + 'static,
35 D: MailDispatch + Sync + Send + 'static,
36 {
37 Self {
38 session: Arc::new(session),
39 dispatch: Arc::new(dispatch),
40 guard: Arc::new(guard),
41 driver: Arc::new(drive),
42 interpret: Arc::new(interpret),
43 }
44 }
45}
46
47impl IoService for Service {
48 fn handle(
49 &self,
50 io: Result<Box<dyn MayBeTls>>,
51 connection: ConnectionInfo,
52 ) -> S1Fut<'static, Result<()>> {
53 let service = self.clone();
54 let driver = self.driver.clone();
55 let interpret = self.interpret.clone();
56
57 trace!("New peer connection {}", connection);
58 let mut state = SmtpContext::new(service, connection);
59
60 Box::pin(async move {
61 driver.drive(&mut io?, &interpret, &mut state).await?;
63 Ok(())
64 })
65 }
66}
67
68impl MailDispatch for Service {
69 fn open_mail_body<'a, 's, 'f>(
70 &'a self,
71 session: &'s mut SmtpSession,
72 ) -> S1Fut<'f, DispatchResult>
73 where
74 'a: 'f,
75 's: 'f,
76 {
77 self.dispatch.open_mail_body(session)
78 }
79}
80
81impl MailGuard for Service {
82 fn add_recipient<'a, 's, 'f>(
83 &'a self,
84 session: &'s mut SmtpSession,
85 rcpt: Recipient,
86 ) -> S2Fut<'f, AddRecipientResult>
87 where
88 'a: 'f,
89 's: 'f,
90 {
91 self.guard.add_recipient(session, rcpt)
92 }
93
94 fn start_mail<'a, 's, 'f>(&'a self, session: &'s mut SmtpSession) -> S2Fut<'f, StartMailResult>
95 where
96 'a: 'f,
97 's: 'f,
98 {
99 self.guard.start_mail(session)
100 }
101}
102
103impl SessionService for Service {
104 fn prepare_session<'a, 'i, 's, 'f>(
105 &'a self,
106 io: &'i mut Box<dyn MayBeTls>,
107 state: &'s mut SmtpContext,
108 ) -> S1Fut<'f, ()>
109 where
110 'a: 'f,
111 'i: 'f,
112 's: 'f,
113 {
114 self.session.prepare_session(io, state)
115 }
116}