1#![deny(
36 missing_copy_implementations,
37 trivial_casts,
38 trivial_numeric_casts,
39 unsafe_code,
40 unstable_features,
41 unused_import_braces,
42 missing_debug_implementations,
43 clippy::unwrap_used
44)]
45
46#[macro_use]
47extern crate log;
48
49pub mod dir;
50mod dispatch;
51#[cfg(feature = "file-transport")]
52pub mod file;
53#[cfg(feature = "journal-transport")]
54pub mod journal;
55#[cfg(feature = "sendmail-transport")]
56pub mod sendmail;
57#[cfg(feature = "smtp-transport")]
58pub mod smtp;
59pub mod stub;
60pub mod types;
61
62pub mod prelude {
63 pub use crate::dir::*;
64 #[cfg(feature = "file-transport")]
65 pub use crate::file::*;
66 #[cfg(feature = "journal-transport")]
67 pub use crate::journal::*;
68 #[cfg(feature = "sendmail-transport")]
69 pub use crate::sendmail::*;
70 #[cfg(feature = "smtp-transport")]
71 pub use crate::smtp::*;
72 pub use crate::types::*;
73 pub use crate::{MailDataStream, Transport};
74}
75
76use crate::types::*;
77use async_std::io::{copy, Write};
78use samotop_core::common::*;
79use std::{fmt, pin::Pin};
80
81pub type SyncFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Sync + Send + 'a>>;
82type SendResult<T> = std::result::Result<<T as Transport>::DataStream, <T as Transport>::Error>;
83
84pub trait Transport: std::fmt::Debug {
86 type DataStream: MailDataStream;
88 type Error;
89
90 fn send_stream<'s, 'a>(&'s self, envelope: Envelope) -> SyncFuture<'a, SendResult<Self>>
92 where
93 's: 'a;
94
95 fn send<'s, 'r, 'a, R>(
97 &'s self,
98 envelope: Envelope,
99 mut message: R,
100 ) -> SyncFuture<'a, SendResult<Self>>
101 where
102 Self::DataStream: Unpin + Send + Sync,
103 Self::Error: From<std::io::Error>,
104 R: io::Read + Unpin + Send + Sync + 'r,
105 's: 'a,
106 'r: 'a,
107 {
108 let stream = self.send_stream(envelope);
109 Box::pin(async move {
110 let mut stream = stream.await?;
111 copy(&mut message, &mut stream).await?;
112 poll_fn(|cx| Pin::new(&mut stream).poll_close(cx)).await?;
113 Ok(stream)
114 })
115 }
116}
117
118pub trait MailDataStream: fmt::Debug + io::Write {
119 fn is_done(&self) -> bool;
123}