Files
lettre/src/client/stream.rs
2014-11-04 17:50:44 +01:00

77 lines
2.4 KiB
Rust

//! TODO
use std::io::net::tcp::TcpStream;
use std::io::IoResult;
use std::str::from_utf8;
use std::vec::Vec;
use response::Response;
use common::{escape_crlf, escape_dot, CRLF};
static BUFFER_SIZE: uint = 1024;
/// TODO
pub trait ClientStream {
/// TODO
fn send_and_get_response(&mut self, string: &str, is_message: bool) -> Response;
/// TODO
fn get_reply(&mut self) -> Option<Response>;
/// TODO
fn read_into_string(&mut self) -> IoResult<String>;
}
impl ClientStream for TcpStream {
/// Sends a complete message or a command to the server and get the response
fn send_and_get_response(&mut self, string: &str, is_message: bool) -> Response {
let end = match is_message {
true => format!("{}.{}", CRLF, CRLF),
false => format!("{}", CRLF)
};
match self.write_str(format!("{}{}", escape_dot(string.to_string()), end).as_slice()) {
Ok(..) => debug!("Wrote: {}", escape_crlf(escape_dot(string.to_string()))),
Err(..) => panic!("Could not write to stream")
}
match self.get_reply() {
Some(response) => response,
None => panic!("No answer")
}
}
/// Reads on the stream into a string
fn read_into_string(&mut self) -> IoResult<String> {
let mut more = true;
let mut result = String::new();
// TODO: Set appropriate timeouts
self.set_timeout(Some(1000));
while more {
let mut buf: Vec<u8> = Vec::with_capacity(BUFFER_SIZE);
let response = match self.push(BUFFER_SIZE, &mut buf) {
Ok(bytes_read) => {
more = bytes_read == BUFFER_SIZE;
if bytes_read > 0 {
from_utf8(buf.slice_to(bytes_read)).unwrap()
} else {
""
}
},
// TODO: Manage error kinds
Err(..) => {more = false; ""},
};
result.push_str(response);
}
debug!("Read: {}", escape_crlf(result.clone()));
return Ok(result);
}
/// Gets the SMTP response
fn get_reply(&mut self) -> Option<Response> {
let response = match self.read_into_string() {
Ok(string) => string,
Err(..) => panic!("No answer")
};
from_str::<Response>(response.as_slice())
}
}