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
use bytes::Bytes; use futures::{Async, AsyncSink, Poll, StartSend}; use hostname::get_hostname; use model::mail::*; use service::*; use tokio::io; use tokio::prelude::future::FutureResult; use tokio::prelude::*; #[derive(Clone)] pub struct ConsoleMail { name: Option<String>, } impl ConsoleMail { pub fn new(name: impl ToString) -> Self { Self { name: Some(name.to_string()), } } pub fn default() -> Self { Self { name: None } } } impl NamedService for ConsoleMail { fn name(&self) -> String { match self.name { None => match get_hostname() { None => "Samotop".into(), Some(name) => name, }, Some(ref name) => name.clone(), } } } impl MailGuard for ConsoleMail { type Future = FutureResult<AcceptRecipientResult, io::Error>; fn accept(&self, request: AcceptRecipientRequest) -> Self::Future { println!("Accepting recipient {:?}", request); future::ok(AcceptRecipientResult::Accepted(request.rcpt)) } } impl MailQueue for ConsoleMail { type Mail = MailSink; type MailFuture = FutureResult<Option<Self::Mail>, io::Error>; fn mail(&self, envelope: Envelope) -> Self::MailFuture { match envelope { Envelope { ref name, peer: Some(ref peer), local: Some(ref local), helo: Some(ref helo), mail: Some(ref mail), ref id, ref rcpts, } if rcpts.len() != 0 => { println!( "Mail from {} (helo: {}, mailid: {}) (peer: {}) for {} on {} ({} <- {})", mail.from(), helo.name(), id, peer, rcpts .iter() .fold(String::new(), |s, r| s + format!("{}, ", r).as_ref()), name, local, peer ); future::ok(Some(MailSink { id: id.clone() })) } envelope => { warn!("Incomplete envelope: {:?}", envelope); future::ok(None) } } } } pub struct MailSink { id: String, } impl Sink for MailSink { type SinkItem = Bytes; type SinkError = io::Error; fn start_send(&mut self, bytes: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> { println!("Mail data for {}: {:?}", self.id, bytes); Ok(AsyncSink::Ready) } fn poll_complete(&mut self) -> Poll<(), Self::SinkError> { Ok(Async::Ready(())) } } impl Mail for MailSink { fn queue(self) -> QueueResult { println!("Mail data finished for {}", self.id); QueueResult::QueuedWithId(self.id) } }