[−][src]Struct new_tokio_smtp::Connection
The basic Connection
type representing an (likely) open smtp connection
It's only likely open as the server could disconnect at any time. But it guaranteed that the last time a command was send over the server did respond with a valid smtp response (through not necessary with a successful one, e.g. the mailbox from a MAIL command might have been rejected or similar)
Normally the only think done with this type is to construct it with
the connect
method, call the send
method or the quit
method (
or the send_mail
cmd if the future is enabled). All other methods
of it are mainly for implementor of the Cmd
trait.
Implementations
impl Connection
[src]
pub fn connect<S, A>(
config: ConnectionConfig<A, S>
) -> impl Future<Item = Connection, Error = ConnectingFailed> + Send where
S: SetupTls,
A: Cmd + Send,
[src]
config: ConnectionConfig<A, S>
) -> impl Future<Item = Connection, Error = ConnectingFailed> + Send where
S: SetupTls,
A: Cmd + Send,
open a connection to an smtp server using given configuration
impl Connection
[src]
pub fn send<C: Cmd>(
self,
cmd: C
) -> impl Future<Item = (Connection, SmtpResult), Error = Error>
[src]
self,
cmd: C
) -> impl Future<Item = (Connection, SmtpResult), Error = Error>
send a command to the smtp server
This consumes the connection (as it might be modified, recrated or killed by the command) and returns a future resolving to the result of sending the command.
Example
use futures::future::{self, Future}; use new_tokio_smtp::{command, Connection, ReversePath, ForwardPath}; let fut = future ::lazy(|| mock_create_connection()) .and_then(|con| { con.send(command::Mail::new( ReversePath::from_unchecked("test@sender.test"))) }) .and_then(|(con, smtp_result)| { // using `ctx_and_then`, or `chain` from would make // thinks more simple (`future_ext::ResultWithContextExt`) if let Err(err) = smtp_result { panic!("server says no {}", err) } con.send(command::Recipient::new( ForwardPath::from_unchecked("test@receiver.test"))) }) .and_then(|(con, smtp_result)| { if let Err(err) = smtp_result { panic!("server says no {}", err) } con.send(command::Data::from_buf(concat!( "Date: Thu, 14 Jun 2018 11:22:18 +0000\r\n", "From: Sendu <test@sender.test>\r\n", "\r\n", "...\r\n" ))) }) .and_then(|(con, smtp_result)| { if let Err(err) = smtp_result { panic!("server says no {}", err) } con.quit() }); // ... this are tokio using operation make sure there is // a running tokio instance/runtime/event loop mock_run_with_tokio(fut);
Logic Failure
A logic failure is a case where the command was successfully send over smtp and a response was successfully received but the response code indicates that the command could not be executed on the smtp server. For example because the mailbox/mail address was rejected.
As long as no connection failure happens the returned future will
resolve to an tuble of the (now again usable) Connection
instance
and a SmtpResult
which is either a Response
or a LogicError
.
The ctx_and_then
or the future_ext::ResultWithContextExt
trait
can be used to chain send
calls in a way that the next call is only
run if there was no error at all (neither connection nor logic error).
Connection Failure
If the connection fails (e.g. the internet connection is interrupted)
the future will resolve to an io::Error
and the connection is gone.
pub fn has_capability<C>(&self, cap: C) -> bool where
C: AsRef<str>,
[src]
C: AsRef<str>,
returns true if the capability is known to be supported, false else wise
The capability is know to be supported if the connection has EhloData and it was in the ehlo data (as a ehlo-keyword in one of the ehlo-lines after the first response line).
If the connection has no ehlo data or the capability is not in the ehlo data false is returned.
pub fn ehlo_data(&self) -> Option<&EhloData>
[src]
returns a opt. reference to the ehlo data stored from the last ehlo call
pub fn into_inner(self) -> Io
[src]
converts the Connection
into an Io
instance
This is only need when implementing custom Cmd
's
pub fn shutdown(self) -> Shutdown<Socket>
[src]
shutdown the connection without sending quit
pub fn quit(self) -> impl Future<Item = Socket, Error = Error>
[src]
sends quit to the server and then shuts down the socket
The socked is shut down independent of wether or not sending quit failed, while sending quit should not cause any logic error if it does it's not returned by this method.
impl Connection
[src]
pub fn send_mail(
self,
envelop: MailEnvelop
) -> impl Future<Item = (Connection, MailSendResult), Error = Error> + Send
[src]
self,
envelop: MailEnvelop
) -> impl Future<Item = (Connection, MailSendResult), Error = Error> + Send
Sends a mail specified through MailEnvelop
through this connection.
If any command fails sending is stopped and RSET
is send to the server
to reset the current mail transaction.
see the module level documentation/README or example dir for example about how to use this.
pub fn send_all_mails<E, M>(con: Connection, mails: M) -> SendAllMails<M> where
E: From<GeneralError>,
M: Iterator<Item = Result<MailEnvelop, E>>,
[src]
E: From<GeneralError>,
M: Iterator<Item = Result<MailEnvelop, E>>,
Sends all mails from mails through the connection.
The connection is moved into the SendAllMails
adapter
and can be retrieved from there.
Alternatively SendAllMails.quit_on_completion
can be used to make the adapter call quite once
all mails are send.
Or SendAllMails.on_completion
can be used if
you need to do something else with the same connection
(like putting it back into a connection pool).
pub fn connect_send_quit<A, E, I, T>(
config: ConnectionConfig<A, T>,
mails: I
) -> impl Stream<Item = (), Error = E> where
A: Cmd,
E: From<GeneralError>,
I: IntoIterator<Item = Result<MailEnvelop, E>>,
T: SetupTls,
[src]
config: ConnectionConfig<A, T>,
mails: I
) -> impl Stream<Item = (), Error = E> where
A: Cmd,
E: From<GeneralError>,
I: IntoIterator<Item = Result<MailEnvelop, E>>,
T: SetupTls,
Creates a new connection, sends all mails and then closes the connection
- if sending a mail fails because of
LogicError
it will still try to send the other mails. - If sending a mail fails because of an I/O-Error causing the connection to be lost the remaining
Mails will fail with
GeneralError::Io
with anstd::io::ErrorKind::NoConnection
error.
This function accepts an IntoIterable
(instead of a Stream
) as all mails
should already be available when the connection os opened.
It also expects Result
's instead of just mails, as mails normally have to
be encoded which can fail (and is not part of the crate). With this its easier
to adapt it to functionality which e.g. takes a vector of data and creates and
sends mails from it returning a vector of results. Be aware of std::iter::once
which provides a handy way to just pass in a single mail envelop.
As any future/stream this has to be polled to drive it to completion, i.e. even if you don't care about the results you have to poll the future and then the stream it resolves to.
Example (where to find it)
Take a look at the send_mail
module documentation for an usage example.
To send a single mail std::iter::once as one
can be used:
Connection::connect_send_quit(config, one(mail))
To get back a Vec
of results you can use:
stream.then(|result| Ok(result)).collect()
Which is only needed as futures v0.1
Stream::collect
method is
conceptually broken. (Stream
's are a sequence of results in futures,
which continuos independent of any error result, but collect
is written
as if streams short circuit once a error is it which is just wrong.)
use std::iter::once as one; // note that the map_err is only needed as `!` isn't stable yet let fut = Connection::connect_send_quit(config, one(mail)) //Stream::collect is conceptually broken in futures v0.1 .then(|res| Result::Ok::<_, ()>(res)) .collect();
Trait Implementations
impl Debug for Connection
[src]
impl From<Connection> for Io
[src]
fn from(con: Connection) -> Self
[src]
impl From<Io> for Connection
[src]
create a new Connection
from a Io
instance
The Io
instance should contain a Socket
which
is still alive.
impl From<Socket> for Connection
[src]
create a new Connection
from a Socket
instance
The Socket
instance should contain a socket which
is still alive.
Auto Trait Implementations
impl !RefUnwindSafe for Connection
impl Send for Connection
impl Sync for Connection
impl Unpin for Connection
impl !UnwindSafe for Connection
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,