mailin_embedded/
lib.rs

1//! A SMTP server that can be embedded into another program
2//!
3//! This library provides a simple embeddable SMTP server. The
4//! server uses blocking IO and a threadpool.
5//! # Examples
6//! ```no_run
7//! use mailin_embedded::{Server, SslConfig, Handler};
8//! # use mailin_embedded::err::Error;
9//!
10//! #[derive(Clone)]
11//! struct MyHandler {}
12//! impl Handler for MyHandler{}
13//!
14//! let handler = MyHandler {};
15//! let mut server = Server::new(handler);
16//!
17//! server.with_name("example.com")
18//!    .with_ssl(SslConfig::None)?
19//!    .with_addr("127.0.0.1:25")?;
20//! server.serve();
21//! # Ok::<(), Error>(())
22//! ```
23
24#![forbid(unsafe_code)]
25#![forbid(missing_docs)]
26
27/// Custom error type for mailin_embedded
28pub mod err;
29
30cfg_if::cfg_if! {
31    if #[cfg(feature = "ossl")] {
32        mod ossl;
33        use crate::ossl::SslImpl;
34    } else {
35        mod rtls;
36        use crate::rtls::SslImpl;
37    }
38}
39
40mod running;
41mod ssl;
42
43use crate::err::Error;
44pub use crate::ssl::SslConfig;
45pub use mailin::response;
46pub use mailin::{Action, AuthMechanism, Handler, Response};
47use std::net::{SocketAddr, TcpListener, ToSocketAddrs};
48
49/// `Server` is used to configure and start the SMTP server
50pub struct Server<H>
51where
52    H: Handler + Clone + Send,
53{
54    handler: H,
55    name: String,
56    ssl: Option<SslImpl>,
57    num_threads: u32,
58    auth: Vec<AuthMechanism>,
59    tcp_listener: Option<TcpListener>,
60    socket_address: Vec<SocketAddr>,
61}
62
63impl<H> Server<H>
64where
65    H: Handler + Clone + Send,
66{
67    /// Create a new server with the given Handler
68    pub fn new(handler: H) -> Self {
69        Self {
70            handler,
71            name: "localhost".to_owned(),
72            ssl: None,
73            num_threads: 4,
74            auth: Vec::with_capacity(4),
75            tcp_listener: None,
76            socket_address: Vec::with_capacity(4),
77        }
78    }
79
80    /// Give the server a name
81    pub fn with_name<T>(&mut self, name: T) -> &mut Self
82    where
83        T: Into<String>,
84    {
85        self.name = name.into();
86        self
87    }
88
89    /// Set the SSL configuration of the server
90    pub fn with_ssl(&mut self, ssl_config: SslConfig) -> Result<&mut Self, Error> {
91        self.ssl = SslImpl::setup(ssl_config)?;
92        Ok(self)
93    }
94
95    /// Set the size of the threadpool which is equal to the maximum number of
96    /// concurrent SMTP sessions.
97    pub fn with_num_threads(&mut self, num_threads: u32) -> &mut Self {
98        self.num_threads = num_threads;
99        self
100    }
101
102    /// Add an authentication mechanism that will supported by the server
103    pub fn with_auth(&mut self, auth: AuthMechanism) -> &mut Self {
104        self.auth.push(auth);
105        self
106    }
107
108    /// Set a tcp listener from an already open socket
109    pub fn with_tcp_listener(&mut self, listener: TcpListener) -> &mut Self {
110        self.tcp_listener = Some(listener);
111        self
112    }
113
114    /// Add ip addresses and ports to listen on.
115    /// Returns an error if the given socket addresses are not valid.
116    /// ```
117    /// # use mailin_embedded::{Server, Handler};
118    /// # use mailin_embedded::err::Error;
119    /// # #[derive(Clone)]
120    /// # struct EmptyHandler {}
121    /// # impl Handler for EmptyHandler {}
122    /// # let mut server = Server::new(EmptyHandler {});
123    /// server.with_addr("127.0.0.1:25")?;
124    /// # Ok::<(), Error>(())
125    /// ```
126    pub fn with_addr<A: ToSocketAddrs>(&mut self, addr: A) -> Result<&mut Self, Error> {
127        for addr in addr
128            .to_socket_addrs()
129            .map_err(|e| Error::with_source("Invalid socket address", e))?
130        {
131            self.socket_address.push(addr);
132        }
133        Ok(self)
134    }
135
136    /// Start the SMTP server and run forever
137    pub fn serve(self) -> Result<(), Error> {
138        running::serve(self)
139    }
140}