Refactored library to be Stream-based, added a wrapper to create streams out of Buffers and Writers, and completed SSL support.
This commit is contained in:
parent
a903dd9571
commit
95234df31f
5 changed files with 140 additions and 92 deletions
|
@ -6,8 +6,11 @@ script:
|
||||||
- chmod +x mktestconfig.sh
|
- chmod +x mktestconfig.sh
|
||||||
- ./mktestconfig.sh
|
- ./mktestconfig.sh
|
||||||
- cargo build --verbose
|
- cargo build --verbose
|
||||||
|
- cargo build --verbose --features ssl
|
||||||
- cargo test --verbose
|
- cargo test --verbose
|
||||||
|
- cargo test --verbose --features ssl
|
||||||
- cargo doc --verbose
|
- cargo doc --verbose
|
||||||
|
- cargo doc --verbose --features ssl
|
||||||
notifications:
|
notifications:
|
||||||
irc:
|
irc:
|
||||||
channels:
|
channels:
|
||||||
|
|
127
src/conn.rs
127
src/conn.rs
|
@ -1,51 +1,60 @@
|
||||||
//! Thread-safe connections on any IrcWriters and IrcReaders.
|
//! Thread-safe connections on any IrcWriters and IrcReaders.
|
||||||
#![experimental]
|
#![experimental]
|
||||||
use std::sync::{Mutex, MutexGuard};
|
use std::sync::{Mutex, MutexGuard};
|
||||||
use std::io::{BufferedReader, BufferedWriter, IoResult, TcpStream};
|
use std::io::{BufferedStream, IoResult, MemWriter, TcpStream};
|
||||||
#[cfg(feature = "ssl")] use std::io::{IoError, OtherIoError};
|
#[cfg(feature = "ssl")] use std::io::{IoError, OtherIoError};
|
||||||
use data::kinds::{IrcWriter, IrcReader};
|
use data::kinds::{IrcReader, IrcStream, IrcWriter};
|
||||||
use data::message::Message;
|
use data::message::Message;
|
||||||
#[cfg(feature = "ssl")] use openssl::ssl::{SslContext, SslStream, Tlsv1};
|
#[cfg(feature = "ssl")] use openssl::ssl::{SslContext, SslStream, Tlsv1};
|
||||||
#[cfg(feature = "ssl")] use openssl::ssl::error::SslError;
|
#[cfg(feature = "ssl")] use openssl::ssl::error::SslError;
|
||||||
|
|
||||||
/// A thread-safe connection.
|
/// A thread-safe connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub struct Connection<T, U> where T: IrcWriter, U: IrcReader {
|
pub struct Connection<T> where T: IrcStream {
|
||||||
writer: Mutex<T>,
|
stream: Mutex<T>
|
||||||
reader: Mutex<U>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Connection<BufferedWriter<TcpStream>, BufferedReader<TcpStream>> {
|
impl Connection<BufferedStream<TcpStream>> {
|
||||||
/// Creates a thread-safe TCP connection to the specified server.
|
/// Creates a thread-safe TCP connection to the specified server.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn connect(host: &str, port: u16) -> IoResult<Connection<BufferedWriter<NetStream>, BufferedReader<NetStream>>> {
|
pub fn connect(host: &str, port: u16) -> IoResult<Connection<BufferedStream<NetStream>>> {
|
||||||
let socket = try!(TcpStream::connect(format!("{}:{}", host, port)[]));
|
let socket = try!(TcpStream::connect(format!("{}:{}", host, port)[]));
|
||||||
Ok(Connection::new(BufferedWriter::new(UnsecuredTcpStream(socket.clone())),
|
Ok(Connection::new(BufferedStream::new(UnsecuredTcpStream(socket))))
|
||||||
BufferedReader::new(UnsecuredTcpStream(socket))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a thread-safe TCP connection to the specified server over SSL.
|
/// Creates a thread-safe TCP connection to the specified server over SSL.
|
||||||
/// If the library is compiled without SSL support, this method panics.
|
/// If the library is compiled without SSL support, this method panics.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
pub fn connect_ssl(host: &str, port: u16) -> IoResult<Connection<BufferedWriter<NetStream>, BufferedReader<NetStream>>> {
|
pub fn connect_ssl(host: &str, port: u16) -> IoResult<Connection<BufferedStream<NetStream>>> {
|
||||||
let socket = try!(TcpStream::connect(format!("{}:{}", host, port)[]));
|
let socket = try!(TcpStream::connect(format!("{}:{}", host, port)[]));
|
||||||
let ssl = try!(ssl_to_io(SslContext::new(Tlsv1)));
|
let ssl = try!(ssl_to_io(SslContext::new(Tlsv1)));
|
||||||
let input = try!(ssl_to_io(SslStream::new(&ssl, socket.clone())));
|
let ssl_socket = try!(ssl_to_io(SslStream::new(&ssl, socket)));
|
||||||
let output = try!(ssl_to_io(SslStream::new(&ssl, socket)));
|
Ok(Connection::new(BufferedStream::new(SslTcpStream(ssl_socket))))
|
||||||
Ok(Connection::new(BufferedWriter::new(SslTcpStream(input)),
|
|
||||||
BufferedReader::new(SslTcpStream(output))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a thread-safe TCP connection to the specified server over SSL.
|
/// Creates a thread-safe TCP connection to the specified server over SSL.
|
||||||
/// If the library is compiled without SSL support, this method panics.
|
/// If the library is compiled without SSL support, this method panics.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[cfg(not(feature = "ssl"))]
|
#[cfg(not(feature = "ssl"))]
|
||||||
pub fn connect_ssl(host: &str, port: u16) -> IoResult<Connection<BufferedWriter<NetStream>, BufferedReader<NetStream>>> {
|
pub fn connect_ssl(host: &str, port: u16) -> IoResult<Connection<BufferedStream<NetStream>>> {
|
||||||
panic!("Cannot connect to {}:{} over SSL without compiling with SSL support.", host, port)
|
panic!("Cannot connect to {}:{} over SSL without compiling with SSL support.", host, port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a Result<T, SslError> into an IoResult<T>.
|
||||||
|
#[cfg(feature = "ssl")]
|
||||||
|
fn ssl_to_io<T>(res: Result<T, SslError>) -> IoResult<T> {
|
||||||
|
match res {
|
||||||
|
Ok(x) => Ok(x),
|
||||||
|
Err(e) => Err(IoError {
|
||||||
|
kind: OtherIoError,
|
||||||
|
desc: "An SSL error occurred.",
|
||||||
|
detail: Some(format!("{}", e)),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An abstraction over different networked streams.
|
/// An abstraction over different networked streams.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub enum NetStream {
|
pub enum NetStream {
|
||||||
|
@ -77,67 +86,99 @@ impl Writer for NetStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ssl")]
|
impl<T: IrcStream> Connection<T> {
|
||||||
fn ssl_to_io<T>(res: Result<T, SslError>) -> IoResult<T> {
|
/// Creates a new connection from any arbitrary IrcStream.
|
||||||
match res {
|
|
||||||
Ok(x) => Ok(x),
|
|
||||||
Err(e) => Err(IoError {
|
|
||||||
kind: OtherIoError,
|
|
||||||
desc: "An SSL error occurred.",
|
|
||||||
detail: Some(format!("{}", e)),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> Connection<T, U> where T: IrcWriter, U: IrcReader {
|
|
||||||
/// Creates a new connection from any arbitrary IrcWriter and IrcReader.
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn new(writer: T, reader: U) -> Connection<T, U> {
|
pub fn new(stream: T) -> Connection<T> {
|
||||||
Connection {
|
Connection {
|
||||||
writer: Mutex::new(writer),
|
stream: Mutex::new(stream),
|
||||||
reader: Mutex::new(reader),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a Message over this connection.
|
/// Sends a Message over this connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn send(&self, message: Message) -> IoResult<()> {
|
pub fn send(&self, message: Message) -> IoResult<()> {
|
||||||
let mut send = self.writer.lock();
|
let mut stream = self.stream.lock();
|
||||||
try!(send.write_str(message.into_string()[]));
|
try!(stream.write_str(message.into_string()[]));
|
||||||
send.flush()
|
stream.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives a single line from this connection.
|
/// Receives a single line from this connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn recv(&self) -> IoResult<String> {
|
pub fn recv(&self) -> IoResult<String> {
|
||||||
self.reader.lock().read_line()
|
self.stream.lock().read_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquires the Writer lock.
|
/// Acquires the Stream lock.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn writer<'a>(&'a self) -> MutexGuard<'a, T> {
|
pub fn stream<'a>(&'a self) -> MutexGuard<'a, T> {
|
||||||
self.writer.lock()
|
self.stream.lock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An IrcStream built from an IrcWriter and an IrcReader.
|
||||||
|
#[experimental]
|
||||||
|
pub struct IoStream<T: IrcWriter, U: IrcReader> {
|
||||||
|
writer: T,
|
||||||
|
reader: U,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: IrcWriter, U: IrcReader> IoStream<T, U> {
|
||||||
|
/// Creates a new IoStream from the given IrcWriter and IrcReader.
|
||||||
|
#[experimental]
|
||||||
|
pub fn new(writer: T, reader: U) -> IoStream<T, U> {
|
||||||
|
IoStream { writer: writer, reader: reader }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U: IrcReader> IoStream<MemWriter, U> {
|
||||||
|
pub fn value(&self) -> Vec<u8> {
|
||||||
|
self.writer.get_ref().to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: IrcWriter, U: IrcReader> Buffer for IoStream<T, U> {
|
||||||
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||||
|
self.reader.fill_buf()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consume(&mut self, amt: uint) {
|
||||||
|
self.reader.consume(amt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: IrcWriter, U: IrcReader> Reader for IoStream<T, U> {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||||
|
self.reader.read(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: IrcWriter, U: IrcReader> Writer for IoStream<T, U> {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||||
|
self.writer.write(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::Connection;
|
use super::{Connection, IoStream};
|
||||||
use std::io::{MemReader, MemWriter};
|
use std::io::{MemReader, MemWriter};
|
||||||
use std::io::util::{NullReader, NullWriter};
|
use std::io::util::{NullReader, NullWriter};
|
||||||
use data::message::Message;
|
use data::message::Message;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn send() {
|
fn send() {
|
||||||
let conn = Connection::new(MemWriter::new(), NullReader);
|
let conn = Connection::new(IoStream::new(MemWriter::new(), NullReader));
|
||||||
assert!(conn.send(Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("Testing!"))).is_ok());
|
assert!(conn.send(Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("Testing!"))).is_ok());
|
||||||
let data = String::from_utf8(conn.writer().get_ref().to_vec()).unwrap();
|
let data = String::from_utf8(conn.stream().value()).unwrap();
|
||||||
assert_eq!(data[], "PRIVMSG test :Testing!\r\n");
|
assert_eq!(data[], "PRIVMSG test :Testing!\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recv() {
|
fn recv() {
|
||||||
let conn = Connection::new(NullWriter, MemReader::new("PRIVMSG test :Testing!\r\n".as_bytes().to_vec()));
|
let conn = Connection::new(IoStream::new(
|
||||||
|
NullWriter, MemReader::new("PRIVMSG test :Testing!\r\n".as_bytes().to_vec())
|
||||||
|
));
|
||||||
assert_eq!(conn.recv().unwrap()[], "PRIVMSG test :Testing!\r\n");
|
assert_eq!(conn.recv().unwrap()[], "PRIVMSG test :Testing!\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@ pub mod kinds {
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub trait IrcReader: Buffer + Sized + Send + 'static {}
|
pub trait IrcReader: Buffer + Sized + Send + 'static {}
|
||||||
impl<T> IrcReader for T where T: Buffer + Sized + Send + 'static {}
|
impl<T> IrcReader for T where T: Buffer + Sized + Send + 'static {}
|
||||||
|
/// Trait describing all possible Streams for this library.
|
||||||
|
#[unstable]
|
||||||
|
pub trait IrcStream: IrcWriter + IrcReader {}
|
||||||
|
impl<T> IrcStream for T where T: IrcWriter + IrcReader {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod command;
|
pub mod command;
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
//! Interface for working with IRC Servers
|
//! Interface for working with IRC Servers
|
||||||
#![experimental]
|
#![experimental]
|
||||||
use std::io::{BufferedReader, BufferedWriter, IoResult};
|
use std::io::{BufferedStream, IoResult};
|
||||||
use conn::{Connection, NetStream};
|
use conn::{Connection, NetStream};
|
||||||
use data::command::{Command, JOIN, PONG};
|
use data::command::{Command, JOIN, PONG};
|
||||||
use data::config::Config;
|
use data::config::Config;
|
||||||
use data::kinds::{IrcReader, IrcWriter};
|
use data::kinds::IrcStream;
|
||||||
use data::message::Message;
|
use data::message::Message;
|
||||||
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
/// Trait describing core Server functionality.
|
/// Trait describing core Server functionality.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub trait Server<'a, T, U> {
|
pub trait Server<'a, T> {
|
||||||
/// Gets the configuration being used with this Server.
|
/// Gets the configuration being used with this Server.
|
||||||
fn config(&self) -> &Config;
|
fn config(&self) -> &Config;
|
||||||
/// Sends a Command to this Server.
|
/// Sends a Command to this Server.
|
||||||
fn send(&self, _: Command) -> IoResult<()>;
|
fn send(&self, _: Command) -> IoResult<()>;
|
||||||
/// Gets an Iterator over Messages received by this Server.
|
/// Gets an Iterator over Messages received by this Server.
|
||||||
fn iter(&'a self) -> ServerIterator<'a, T, U>;
|
fn iter(&'a self) -> ServerIterator<'a, T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A thread-safe implementation of an IRC Server connection.
|
/// A thread-safe implementation of an IRC Server connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub struct IrcServer<'a, T, U> where T: IrcWriter, U: IrcReader {
|
pub struct IrcServer<'a, T> where T: IrcStream {
|
||||||
/// The thread-safe IRC connection.
|
/// The thread-safe IRC connection.
|
||||||
conn: Connection<T, U>,
|
conn: Connection<T>,
|
||||||
/// The configuration used with this connection.
|
/// The configuration used with this connection.
|
||||||
config: Config
|
config: Config
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IrcServer<'a, BufferedWriter<NetStream>, BufferedReader<NetStream>> {
|
impl<'a> IrcServer<'a, BufferedStream<NetStream>> {
|
||||||
/// Creates a new IRC Server connection from the configuration at the specified path, connecting immediately.
|
/// Creates a new IRC Server connection from the configuration at the specified path, connecting immediately.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn new(config: &str) -> IoResult<IrcServer<'a, BufferedWriter<NetStream>, BufferedReader<NetStream>>> {
|
pub fn new(config: &str) -> IoResult<IrcServer<'a, BufferedStream<NetStream>>> {
|
||||||
let config = try!(Config::load_utf8(config));
|
let config = try!(Config::load_utf8(config));
|
||||||
let conn = try!(if config.use_ssl {
|
let conn = try!(if config.use_ssl {
|
||||||
Connection::connect_ssl(config.server[], config.port)
|
Connection::connect_ssl(config.server[], config.port)
|
||||||
|
@ -44,7 +44,7 @@ impl<'a> IrcServer<'a, BufferedWriter<NetStream>, BufferedReader<NetStream>> {
|
||||||
|
|
||||||
/// Creates a new IRC server connection from the specified configuration, connecting immediately.
|
/// Creates a new IRC server connection from the specified configuration, connecting immediately.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn from_config(config: Config) -> IoResult<IrcServer<'a, BufferedWriter<NetStream>, BufferedReader<NetStream>>> {
|
pub fn from_config(config: Config) -> IoResult<IrcServer<'a, BufferedStream<NetStream>>> {
|
||||||
let conn = try!(if config.use_ssl {
|
let conn = try!(if config.use_ssl {
|
||||||
Connection::connect_ssl(config.server[], config.port)
|
Connection::connect_ssl(config.server[], config.port)
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,7 +54,7 @@ impl<'a> IrcServer<'a, BufferedWriter<NetStream>, BufferedReader<NetStream>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> Server<'a, T, U> for IrcServer<'a, T, U> where T: IrcWriter, U: IrcReader {
|
impl<'a, T> Server<'a, T> for IrcServer<'a, T> where T: IrcStream {
|
||||||
fn config(&self) -> &Config {
|
fn config(&self) -> &Config {
|
||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
|
@ -63,15 +63,15 @@ impl<'a, T, U> Server<'a, T, U> for IrcServer<'a, T, U> where T: IrcWriter, U: I
|
||||||
self.conn.send(command.to_message())
|
self.conn.send(command.to_message())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter(&'a self) -> ServerIterator<'a, T, U> {
|
fn iter(&'a self) -> ServerIterator<'a, T> {
|
||||||
ServerIterator::new(self)
|
ServerIterator::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> IrcServer<'a, T, U> where T: IrcWriter, U: IrcReader {
|
impl<'a, T> IrcServer<'a, T> where T: IrcStream {
|
||||||
/// Creates an IRC server from the specified configuration, and any arbitrary Connection.
|
/// Creates an IRC server from the specified configuration, and any arbitrary Connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn from_connection(config: Config, conn: Connection<T, U>) -> IrcServer<'a, T, U> {
|
pub fn from_connection(config: Config, conn: Connection<T>) -> IrcServer<'a, T> {
|
||||||
IrcServer {
|
IrcServer {
|
||||||
conn: conn,
|
conn: conn,
|
||||||
config: config
|
config: config
|
||||||
|
@ -79,7 +79,7 @@ impl<'a, T, U> IrcServer<'a, T, U> where T: IrcWriter, U: IrcReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to the IRC server's connection.
|
/// Gets a reference to the IRC server's connection.
|
||||||
pub fn conn(&self) -> &Connection<T, U> {
|
pub fn conn(&self) -> &Connection<T> {
|
||||||
&self.conn
|
&self.conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,21 +99,21 @@ impl<'a, T, U> IrcServer<'a, T, U> where T: IrcWriter, U: IrcReader {
|
||||||
|
|
||||||
/// An Iterator over an IrcServer's incoming Messages.
|
/// An Iterator over an IrcServer's incoming Messages.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub struct ServerIterator<'a, T, U> where T: IrcWriter, U: IrcReader {
|
pub struct ServerIterator<'a, T> where T: IrcStream {
|
||||||
pub server: &'a IrcServer<'a, T, U>
|
pub server: &'a IrcServer<'a, T>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> ServerIterator<'a, T, U> where T: IrcWriter, U: IrcReader {
|
impl<'a, T> ServerIterator<'a, T> where T: IrcStream {
|
||||||
/// Creates a new ServerIterator for the desired IrcServer.
|
/// Creates a new ServerIterator for the desired IrcServer.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn new(server: &'a IrcServer<'a, T, U>) -> ServerIterator<'a, T, U> {
|
pub fn new(server: &'a IrcServer<'a, T>) -> ServerIterator<'a, T> {
|
||||||
ServerIterator {
|
ServerIterator {
|
||||||
server: server
|
server: server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> Iterator<Message> for ServerIterator<'a, T, U> where T: IrcWriter, U: IrcReader {
|
impl<'a, T> Iterator<Message> for ServerIterator<'a, T> where T: IrcStream {
|
||||||
fn next(&mut self) -> Option<Message> {
|
fn next(&mut self) -> Option<Message> {
|
||||||
let line = self.server.conn.recv();
|
let line = self.server.conn.recv();
|
||||||
match line {
|
match line {
|
||||||
|
@ -133,7 +133,7 @@ mod test {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{MemReader, MemWriter};
|
use std::io::{MemReader, MemWriter};
|
||||||
use std::io::util::{NullReader, NullWriter};
|
use std::io::util::{NullReader, NullWriter};
|
||||||
use conn::Connection;
|
use conn::{Connection, IoStream};
|
||||||
use data::Config;
|
use data::Config;
|
||||||
use data::command::PRIVMSG;
|
use data::command::PRIVMSG;
|
||||||
use data::kinds::IrcReader;
|
use data::kinds::IrcReader;
|
||||||
|
@ -153,15 +153,15 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_server_value<U>(server: IrcServer<MemWriter, U>) -> String where U: IrcReader {
|
pub fn get_server_value<U>(server: IrcServer<IoStream<MemWriter, U>>) -> String where U: IrcReader {
|
||||||
String::from_utf8(server.conn().writer().get_ref().to_vec()).unwrap()
|
String::from_utf8(server.conn().stream().value()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn iterator() {
|
fn iterator() {
|
||||||
let exp = "PRIVMSG test :Hi!\r\nPRIVMSG test :This is a test!\r\n:test!test@test JOIN #test\r\n";
|
let exp = "PRIVMSG test :Hi!\r\nPRIVMSG test :This is a test!\r\n:test!test@test JOIN #test\r\n";
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(NullWriter, MemReader::new(exp.as_bytes().to_vec())));
|
Connection::new(IoStream::new(NullWriter, MemReader::new(exp.as_bytes().to_vec()))));
|
||||||
let mut messages = String::new();
|
let mut messages = String::new();
|
||||||
for message in server.iter() {
|
for message in server.iter() {
|
||||||
messages.push_str(message.into_string()[]);
|
messages.push_str(message.into_string()[]);
|
||||||
|
@ -173,7 +173,7 @@ mod test {
|
||||||
fn handle_message() {
|
fn handle_message() {
|
||||||
let value = "PING :irc.test.net\r\n:irc.test.net 376 test :End of /MOTD command.\r\n";
|
let value = "PING :irc.test.net\r\n:irc.test.net 376 test :End of /MOTD command.\r\n";
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), MemReader::new(value.as_bytes().to_vec())));
|
Connection::new(IoStream::new(MemWriter::new(), MemReader::new(value.as_bytes().to_vec()))));
|
||||||
for message in server.iter() {
|
for message in server.iter() {
|
||||||
println!("{}", message);
|
println!("{}", message);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send() {
|
fn send() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
assert!(server.send(PRIVMSG("#test", "Hi there!")).is_ok());
|
assert!(server.send(PRIVMSG("#test", "Hi there!")).is_ok());
|
||||||
assert_eq!(get_server_value(server)[],
|
assert_eq!(get_server_value(server)[],
|
||||||
"PRIVMSG #test :Hi there!\r\n");
|
"PRIVMSG #test :Hi there!\r\n");
|
||||||
|
|
|
@ -5,16 +5,16 @@ use std::io::IoResult;
|
||||||
use data::command::{Command, INVITE, JOIN, KILL, MODE, NICK, KICK};
|
use data::command::{Command, INVITE, JOIN, KILL, MODE, NICK, KICK};
|
||||||
use data::command::{OPER, PONG, PRIVMSG, SAMODE, SANICK, TOPIC, USER};
|
use data::command::{OPER, PONG, PRIVMSG, SAMODE, SANICK, TOPIC, USER};
|
||||||
use data::config::Config;
|
use data::config::Config;
|
||||||
use data::kinds::{IrcReader, IrcWriter};
|
use data::kinds::IrcStream;
|
||||||
use server::{Server, ServerIterator};
|
use server::{Server, ServerIterator};
|
||||||
|
|
||||||
/// Functionality-providing wrapper for Server.
|
/// Functionality-providing wrapper for Server.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub struct Wrapper<'a, T, U> where T: IrcWriter, U: IrcReader {
|
pub struct Wrapper<'a, T> where T: IrcStream {
|
||||||
server: &'a Server<'a, T, U> + 'a
|
server: &'a Server<'a, T> + 'a
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> Server<'a, T, U> for Wrapper<'a, T, U> where T: IrcWriter, U: IrcReader {
|
impl<'a, T> Server<'a, T> for Wrapper<'a, T> where T: IrcStream {
|
||||||
fn config(&self) -> &Config {
|
fn config(&self) -> &Config {
|
||||||
self.server.config()
|
self.server.config()
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,15 @@ impl<'a, T, U> Server<'a, T, U> for Wrapper<'a, T, U> where T: IrcWriter, U: Irc
|
||||||
self.server.send(command)
|
self.server.send(command)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter(&'a self) -> ServerIterator<'a, T, U> {
|
fn iter(&'a self) -> ServerIterator<'a, T> {
|
||||||
self.server.iter()
|
self.server.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> Wrapper<'a, T, U> where T: IrcWriter, U: IrcReader {
|
impl<'a, T> Wrapper<'a, T> where T: IrcStream {
|
||||||
/// Creates a new Wrapper from the given Server.
|
/// Creates a new Wrapper from the given Server.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn new(server: &'a Server<'a, T, U>) -> Wrapper<'a, T, U> {
|
pub fn new(server: &'a Server<'a, T>) -> Wrapper<'a, T> {
|
||||||
Wrapper { server: server }
|
Wrapper { server: server }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,14 +137,14 @@ mod test {
|
||||||
use super::Wrapper;
|
use super::Wrapper;
|
||||||
use std::io::MemWriter;
|
use std::io::MemWriter;
|
||||||
use std::io::util::NullReader;
|
use std::io::util::NullReader;
|
||||||
use conn::Connection;
|
use conn::{Connection, IoStream};
|
||||||
use server::IrcServer;
|
use server::IrcServer;
|
||||||
use server::test::{get_server_value, test_config};
|
use server::test::{get_server_value, test_config};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn identify() {
|
fn identify() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.identify().unwrap();
|
wrapper.identify().unwrap();
|
||||||
|
@ -156,7 +156,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_pong() {
|
fn send_pong() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_pong("irc.test.net").unwrap();
|
wrapper.send_pong("irc.test.net").unwrap();
|
||||||
|
@ -168,7 +168,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_join() {
|
fn send_join() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_join("#test,#test2,#test3").unwrap();
|
wrapper.send_join("#test,#test2,#test3").unwrap();
|
||||||
|
@ -180,7 +180,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_oper() {
|
fn send_oper() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_oper("test", "test").unwrap();
|
wrapper.send_oper("test", "test").unwrap();
|
||||||
|
@ -192,7 +192,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_privmsg() {
|
fn send_privmsg() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_privmsg("#test", "Hi, everybody!").unwrap();
|
wrapper.send_privmsg("#test", "Hi, everybody!").unwrap();
|
||||||
|
@ -204,7 +204,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_topic_no_topic() {
|
fn send_topic_no_topic() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_topic("#test", "").unwrap();
|
wrapper.send_topic("#test", "").unwrap();
|
||||||
|
@ -216,7 +216,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_topic() {
|
fn send_topic() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_topic("#test", "Testing stuff.").unwrap();
|
wrapper.send_topic("#test", "Testing stuff.").unwrap();
|
||||||
|
@ -228,7 +228,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_kill() {
|
fn send_kill() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_kill("test", "Testing kills.").unwrap();
|
wrapper.send_kill("test", "Testing kills.").unwrap();
|
||||||
|
@ -240,7 +240,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_kick_no_message() {
|
fn send_kick_no_message() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_kick("#test", "test", "").unwrap();
|
wrapper.send_kick("#test", "test", "").unwrap();
|
||||||
|
@ -252,7 +252,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_kick() {
|
fn send_kick() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_kick("#test", "test", "Testing kicks.").unwrap();
|
wrapper.send_kick("#test", "test", "Testing kicks.").unwrap();
|
||||||
|
@ -264,7 +264,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_mode_no_modeparams() {
|
fn send_mode_no_modeparams() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_mode("#test", "+i", "").unwrap();
|
wrapper.send_mode("#test", "+i", "").unwrap();
|
||||||
|
@ -276,7 +276,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_mode() {
|
fn send_mode() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_mode("#test", "+o", "test").unwrap();
|
wrapper.send_mode("#test", "+o", "test").unwrap();
|
||||||
|
@ -288,7 +288,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_samode_no_modeparams() {
|
fn send_samode_no_modeparams() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_samode("#test", "+i", "").unwrap();
|
wrapper.send_samode("#test", "+i", "").unwrap();
|
||||||
|
@ -300,7 +300,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_samode() {
|
fn send_samode() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_samode("#test", "+o", "test").unwrap();
|
wrapper.send_samode("#test", "+o", "test").unwrap();
|
||||||
|
@ -312,7 +312,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_sanick() {
|
fn send_sanick() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_sanick("test", "test2").unwrap();
|
wrapper.send_sanick("test", "test2").unwrap();
|
||||||
|
@ -324,7 +324,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn send_invite() {
|
fn send_invite() {
|
||||||
let server = IrcServer::from_connection(test_config(),
|
let server = IrcServer::from_connection(test_config(),
|
||||||
Connection::new(MemWriter::new(), NullReader));
|
Connection::new(IoStream::new(MemWriter::new(), NullReader)));
|
||||||
{
|
{
|
||||||
let wrapper = Wrapper::new(&server);
|
let wrapper = Wrapper::new(&server);
|
||||||
wrapper.send_invite("test", "#test").unwrap();
|
wrapper.send_invite("test", "#test").unwrap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue