Start refactoring streams to introduce a mock server
This commit is contained in:
@@ -28,7 +28,7 @@ fn main() {
|
||||
.subject("Hello")
|
||||
.build();
|
||||
|
||||
let mut sender: Sender<TcpStream> = SenderBuilder::localhost().hello_name("localhost")
|
||||
let mut sender: Sender = SenderBuilder::localhost().hello_name("localhost")
|
||||
.enable_connection_reuse(true).build();
|
||||
|
||||
for _ in (1..5) {
|
||||
|
||||
@@ -10,17 +10,16 @@
|
||||
//! SMTP client
|
||||
|
||||
use std::string::String;
|
||||
use std::net::TcpStream;
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
use std::io::{BufRead, BufStream, Read, Write};
|
||||
|
||||
use response::{Response, Severity, Category};
|
||||
use error::SmtpResult;
|
||||
use client::connecter::Connecter;
|
||||
use client::net::{Connector, SmtpStream};
|
||||
use client::authentication::{plain, cram_md5};
|
||||
use {CRLF, MESSAGE_ENDING};
|
||||
|
||||
pub mod connecter;
|
||||
pub mod net;
|
||||
mod authentication;
|
||||
|
||||
/// Returns the string after adding a dot at the beginning of each line starting with a dot
|
||||
@@ -43,7 +42,7 @@ fn escape_crlf(string: &str) -> String {
|
||||
}
|
||||
|
||||
/// Structure that implements the SMTP client
|
||||
pub struct Client<S: Write + Read = TcpStream> {
|
||||
pub struct Client<S: Write + Read = SmtpStream> {
|
||||
/// TCP stream between client and server
|
||||
/// Value is None before connection
|
||||
stream: Option<BufStream<S>>,
|
||||
@@ -58,7 +57,7 @@ macro_rules! return_err (
|
||||
})
|
||||
);
|
||||
|
||||
impl<S: Write + Read = TcpStream> Client<S> {
|
||||
impl<S: Write + Read = SmtpStream> Client<S> {
|
||||
/// Creates a new SMTP client
|
||||
///
|
||||
/// It does not connects to the server, but only creates the `Client`
|
||||
@@ -70,7 +69,7 @@ impl<S: Write + Read = TcpStream> Client<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Connecter + Write + Read = TcpStream> Client<S> {
|
||||
impl<S: Connector + Write + Read = SmtpStream> Client<S> {
|
||||
/// Closes the SMTP transaction if possible
|
||||
pub fn close(&mut self) {
|
||||
let _ = self.quit();
|
||||
@@ -85,7 +84,7 @@ impl<S: Connecter + Write + Read = TcpStream> Client<S> {
|
||||
}
|
||||
|
||||
// Try to connect
|
||||
self.stream = Some(BufStream::new(try!(Connecter::connect(&self.server_addr))));
|
||||
self.stream = Some(BufStream::new(try!(Connector::connect(&self.server_addr))));
|
||||
|
||||
self.get_reply()
|
||||
}
|
||||
@@ -172,7 +171,7 @@ impl<S: Connecter + Write + Read = TcpStream> Client<S> {
|
||||
self.command(&format!("AUTH CRAM-MD5 {}", cram_md5(username, password, &encoded_challenge)))
|
||||
}
|
||||
|
||||
/// Sends the message content and close
|
||||
/// Sends the message content
|
||||
pub fn message(&mut self, message_content: &str) -> SmtpResult {
|
||||
self.send_server(&escape_dot(message_content), MESSAGE_ENDING)
|
||||
}
|
||||
|
||||
@@ -7,20 +7,24 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! A trait to represent a connected stream
|
||||
//! A trait to represent a stream
|
||||
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use std::net::TcpStream;
|
||||
|
||||
/// A trait for the concept of opening a stream
|
||||
pub trait Connecter {
|
||||
pub trait Connector {
|
||||
/// Opens a connection to the given IP socket
|
||||
fn connect(addr: &SocketAddr) -> io::Result<Self>;
|
||||
}
|
||||
|
||||
impl Connecter for TcpStream {
|
||||
fn connect(addr: &SocketAddr) -> io::Result<TcpStream> {
|
||||
impl Connector for SmtpStream {
|
||||
fn connect(addr: &SocketAddr) -> io::Result<SmtpStream> {
|
||||
TcpStream::connect(addr)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an atual SMTP network stream
|
||||
//Used later for ssl
|
||||
pub type SmtpStream = TcpStream;
|
||||
12
src/lib.rs
12
src/lib.rs
@@ -40,7 +40,6 @@
|
||||
//! ```rust,no_run
|
||||
//! use smtp::sender::{Sender, SenderBuilder};
|
||||
//! use smtp::mailer::EmailBuilder;
|
||||
//! use std::net::TcpStream;
|
||||
//!
|
||||
//! // Create an email
|
||||
//! let email = EmailBuilder::new()
|
||||
@@ -53,7 +52,7 @@
|
||||
//! .build();
|
||||
//!
|
||||
//! // Open a local connection on port 25
|
||||
//! let mut sender: Sender<TcpStream> = SenderBuilder::localhost().build();
|
||||
//! let mut sender = SenderBuilder::localhost().build();
|
||||
//! // Send the email
|
||||
//! let result = sender.send(email);
|
||||
//!
|
||||
@@ -65,7 +64,6 @@
|
||||
//! ```rust,no_run
|
||||
//! use smtp::sender::{Sender, SenderBuilder};
|
||||
//! use smtp::mailer::EmailBuilder;
|
||||
//! use std::net::TcpStream;
|
||||
//!
|
||||
//! let mut builder = EmailBuilder::new();
|
||||
//! builder = builder.to(("user@example.org", "Alias name"));
|
||||
@@ -81,7 +79,7 @@
|
||||
//! let email = builder.build();
|
||||
//!
|
||||
//! // Connect to a remote server on a custom port
|
||||
//! let mut sender: Sender<TcpStream> = SenderBuilder::new(("server.tld", 10025))
|
||||
//! let mut sender = SenderBuilder::new(("server.tld", 10025))
|
||||
//! // Set the name sent during EHLO/HELO, default is `localhost`
|
||||
//! .hello_name("my.hostname.tld")
|
||||
//! // Add credentials for authentication
|
||||
@@ -107,7 +105,6 @@
|
||||
//! ```rust,no_run
|
||||
//! use smtp::sender::{Sender, SenderBuilder};
|
||||
//! use smtp::sendable_email::SimpleSendableEmail;
|
||||
//! use std::net::TcpStream;
|
||||
//!
|
||||
//! // Create a minimal email
|
||||
//! let email = SimpleSendableEmail::new(
|
||||
@@ -116,7 +113,7 @@
|
||||
//! "Hello world !"
|
||||
//! );
|
||||
//!
|
||||
//! let mut sender: Sender<TcpStream> = SenderBuilder::localhost().build();
|
||||
//! let mut sender = SenderBuilder::localhost().build();
|
||||
//! let result = sender.send(email);
|
||||
//! assert!(result.is_ok());
|
||||
//! ```
|
||||
@@ -127,10 +124,11 @@
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use smtp::client::Client;
|
||||
//! use smtp::client::net::SmtpStream;
|
||||
//! use smtp::SMTP_PORT;
|
||||
//! use std::net::TcpStream;
|
||||
//!
|
||||
//! let mut email_client: Client<TcpStream> = Client::new(("localhost", SMTP_PORT));
|
||||
//! let mut email_client: Client<SmtpStream> = Client::new(("localhost", SMTP_PORT));
|
||||
//! let _ = email_client.connect();
|
||||
//! let _ = email_client.ehlo("my_hostname");
|
||||
//! let _ = email_client.mail("user@example.com", None);
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
//! Sends an email using the client
|
||||
|
||||
use std::string::String;
|
||||
use std::net::TcpStream;
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -22,7 +20,7 @@ use error::{SmtpResult, SmtpError};
|
||||
use sendable_email::SendableEmail;
|
||||
use sender::server_info::ServerInfo;
|
||||
use client::Client;
|
||||
use client::connecter::Connecter;
|
||||
use client::net::SmtpStream;
|
||||
|
||||
mod server_info;
|
||||
|
||||
@@ -87,7 +85,7 @@ impl SenderBuilder {
|
||||
/// Build the SMTP client
|
||||
///
|
||||
/// It does not connects to the server, but only creates the `Sender`
|
||||
pub fn build<S: Connecter + Read + Write>(self) -> Sender<S> {
|
||||
pub fn build(self) -> Sender {
|
||||
Sender::new(self)
|
||||
}
|
||||
}
|
||||
@@ -102,7 +100,7 @@ struct State {
|
||||
}
|
||||
|
||||
/// Structure that implements the high level SMTP client
|
||||
pub struct Sender<S: Write + Read = TcpStream> {
|
||||
pub struct Sender {
|
||||
/// Information about the server
|
||||
/// Value is None before HELO/EHLO
|
||||
server_info: Option<ServerInfo>,
|
||||
@@ -111,7 +109,7 @@ pub struct Sender<S: Write + Read = TcpStream> {
|
||||
/// Information about the client
|
||||
client_info: SenderBuilder,
|
||||
/// Low level client
|
||||
client: Client<S>,
|
||||
client: Client<SmtpStream>,
|
||||
}
|
||||
|
||||
macro_rules! try_smtp (
|
||||
@@ -129,12 +127,12 @@ macro_rules! try_smtp (
|
||||
})
|
||||
);
|
||||
|
||||
impl<S: Write + Read = TcpStream> Sender<S> {
|
||||
impl Sender {
|
||||
/// Creates a new SMTP client
|
||||
///
|
||||
/// It does not connects to the server, but only creates the `Sender`
|
||||
pub fn new(builder: SenderBuilder) -> Sender<S> {
|
||||
let client: Client<S> = Client::new(builder.server_addr);
|
||||
pub fn new(builder: SenderBuilder) -> Sender {
|
||||
let client: Client<SmtpStream> = Client::new(builder.server_addr);
|
||||
Sender{
|
||||
client: client,
|
||||
server_info: None,
|
||||
@@ -145,9 +143,7 @@ impl<S: Write + Read = TcpStream> Sender<S> {
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Connecter + Write + Read = TcpStream> Sender<S> {
|
||||
/// Reset the client state
|
||||
fn reset(&mut self) {
|
||||
// Close the SMTP transaction if needed
|
||||
|
||||
Reference in New Issue
Block a user