samotop_delivery/stub/
mod.rs

1//! The stub transport only logs message envelope and drops the content. It can be useful for
2//! testing purposes.
3//!
4
5mod error;
6
7pub use self::error::*;
8use crate::{
9    stub::error::{Error, StubResult},
10    Envelope, MailDataStream, SyncFuture, Transport,
11};
12use samotop_core::common::*;
13
14/// This transport logs the message envelope and returns the given response
15#[derive(Debug)]
16pub struct StubTransport {
17    response: StubResult,
18}
19
20impl StubTransport {
21    /// Creates a new transport that always returns the given response
22    pub fn new(response: StubResult) -> StubTransport {
23        StubTransport { response }
24    }
25
26    /// Creates a new transport that always returns a success response
27    pub fn new_positive() -> StubTransport {
28        StubTransport { response: Ok(()) }
29    }
30}
31
32impl Transport for StubTransport {
33    type DataStream = StubStream;
34    type Error = Error;
35    fn send_stream<'life1, 'async_trait>(
36        &'life1 self,
37        envelope: Envelope,
38    ) -> SyncFuture<std::result::Result<StubStream, Error>>
39    where
40        'life1: 'async_trait,
41    {
42        info!(
43            "{}: from=<{}> to=<{:?}>",
44            envelope.message_id(),
45            match envelope.from() {
46                Some(address) => address.to_string(),
47                None => "".to_string(),
48            },
49            envelope.to()
50        );
51        Box::pin(ready(Ok(StubStream {
52            response: self.response.clone(),
53        })))
54    }
55}
56
57#[derive(Debug)]
58pub struct StubStream {
59    response: StubResult,
60}
61
62impl MailDataStream for StubStream {
63    fn is_done(&self) -> bool {
64        info!("Done: {:?}", self.response);
65        self.response.is_ok()
66    }
67}
68
69impl io::Write for StubStream {
70    fn poll_write(
71        self: Pin<&mut Self>,
72        _cx: &mut Context<'_>,
73        buf: &[u8],
74    ) -> Poll<std::io::Result<usize>> {
75        info!("Writing {} bytes", buf.len());
76        Poll::Ready(Ok(buf.len()))
77    }
78    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
79        info!("Flushing");
80        Poll::Ready(Ok(()))
81    }
82    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
83        info!("Closing");
84        Poll::Ready(self.response.as_ref().map(|_resp| ()))
85            .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.clone()))
86    }
87}