Reconnection no longer requires mutability, Wrapper now has

send_quit(...).
This commit is contained in:
Aaron Weiss 2014-12-20 20:12:29 -05:00
parent 49c96e9ece
commit 86a5faaa1d
3 changed files with 54 additions and 24 deletions

View file

@ -19,41 +19,65 @@ pub struct Connection<T: IrcReader, U: IrcWriter> {
/// A Connection over a buffered NetStream.
pub type NetConnection = Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>>;
/// An internal type
type NetReaderWriterPair = (BufferedReader<NetStream>, BufferedWriter<NetStream>);
impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
/// Creates a thread-safe TCP connection to the specified server.
#[experimental]
pub fn connect(host: &str, port: u16)
-> IoResult<NetConnection> {
pub fn connect(host: &str, port: u16) -> IoResult<NetConnection> {
let (reader, writer) = try!(Connection::connect_internal(host, port));
Ok(Connection::new(reader, writer))
}
/// connects to the specified server and returns a reader-writer pair.
fn connect_internal(host: &str, port: u16) -> IoResult<NetReaderWriterPair> {
let socket = try!(TcpStream::connect(format!("{}:{}", host, port)[]));
Ok(Connection::new(
BufferedReader::new(NetStream::UnsecuredTcpStream(socket.clone())),
BufferedWriter::new(NetStream::UnsecuredTcpStream(socket))
))
Ok((BufferedReader::new(NetStream::UnsecuredTcpStream(socket.clone())),
BufferedWriter::new(NetStream::UnsecuredTcpStream(socket))))
}
/// Creates a thread-safe TCP connection to the specified server over SSL.
/// If the library is compiled without SSL support, this method panics.
#[experimental]
#[cfg(feature = "ssl")]
pub fn connect_ssl(host: &str, port: u16) -> IoResult<NetConnection> {
let (reader, writer) = try!(Connection::connect_ssl_internal(host, port));
Ok(Connection::new(reader, writer))
}
/// Connects over SSL to the specified server and returns a reader-writer pair.
#[cfg(feature = "ssl")]
fn connect_ssl_internal(host: &str, port: u16) -> IoResult<NetReaderWriterPair> {
let socket = try!(TcpStream::connect(format!("{}:{}", host, port)[]));
let ssl = try!(ssl_to_io(SslContext::new(SslMethod::Tlsv1)));
let ssl_socket = try!(ssl_to_io(SslStream::new(&ssl, socket)));
Ok(Connection::new(
BufferedReader::new(NetStream::SslTcpStream(ssl_socket.clone())),
BufferedWriter::new(NetStream::SslTcpStream(ssl_socket)),
))
Ok((BufferedReader::new(NetStream::SslTcpStream(ssl_socket.clone())),
BufferedWriter::new(NetStream::SslTcpStream(ssl_socket))))
}
/// Creates a thread-safe TCP connection to the specified server over SSL.
/// If the library is compiled without SSL support, this method panics.
#[experimental]
/// Panics because SSL support is not compiled in.
#[cfg(not(feature = "ssl"))]
pub fn connect_ssl(host: &str, port: u16)
-> IoResult<NetConnection> {
fn connect_ssl_internal(host: &str, port: u16) -> IoResult<NetReaderWriterPair> {
panic!("Cannot connect to {}:{} over SSL without compiling with SSL support.", host, port)
}
/// Reconnects to the specified server, dropping the current connection.
pub fn reconnect(&self, host: &str, port: u16) -> IoResult<()> {
let use_ssl = match self.reader.lock().get_ref() {
&NetStream::UnsecuredTcpStream(_) => false,
#[cfg(feature = "ssl")]
&NetStream::SslTcpStream(_) => true,
};
let (reader, writer) = if use_ssl {
try!(Connection::connect_ssl_internal(host, port))
} else {
try!(Connection::connect_internal(host, port))
};
*self.reader.lock() = reader;
*self.writer.lock() = writer;
Ok(())
}
/// Sets the keepalive for the network stream.
#[experimental]

View file

@ -62,13 +62,8 @@ impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
/// Reconnects to the IRC server.
#[experimental]
pub fn reconnect(&mut self) -> IoResult<()> {
self.conn = try!(if self.config.use_ssl() {
Connection::connect_ssl(self.config.server(), self.config.port())
} else {
Connection::connect(self.config.server(), self.config.port())
});
Ok(())
pub fn reconnect(&self) -> IoResult<()> {
self.conn.reconnect(self.config().server(), self.config.port())
}
}

View file

@ -4,7 +4,7 @@
use std::io::IoResult;
use data::{Command, Config, User};
use data::Command::{CAP, INVITE, JOIN, KICK, KILL, MODE, NICK, NOTICE};
use data::Command::{OPER, PASS, PONG, PRIVMSG, SAMODE, SANICK, TOPIC, USER};
use data::Command::{OPER, PASS, PONG, PRIVMSG, QUIT, SAMODE, SANICK, TOPIC, USER};
use data::command::CapSubCommand::{END, REQ};
use data::kinds::{IrcReader, IrcWriter};
use server::{Server, ServerIterator};
@ -153,6 +153,17 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
pub fn send_invite(&self, nick: &str, chan: &str) -> IoResult<()> {
self.server.send(INVITE(nick, chan))
}
/// Quits the server entirely with a message.
/// This defaults to `Powered by Rust.` if none is specified.
#[experimental]
pub fn send_quit(&self, msg: &str) -> IoResult<()> {
self.server.send(QUIT(Some(if msg.len() == 0 {
"Powered by Rust."
} else {
msg
})))
}
}
#[cfg(test)]