Migrated to new std::io.
This commit is contained in:
parent
9d695a1ee5
commit
8bc8b946f7
8 changed files with 221 additions and 217 deletions
|
@ -2,72 +2,76 @@
|
|||
#![stable]
|
||||
#[cfg(feature = "ssl")] use std::borrow::ToOwned;
|
||||
#[cfg(feature = "ssl")] use std::error::Error;
|
||||
use std::old_io::{BufferedReader, BufferedWriter, IoResult, TcpStream};
|
||||
#[cfg(any(feature = "encode", feature = "ssl"))] use std::old_io::{IoError, IoErrorKind};
|
||||
use std::io::prelude::*;
|
||||
use std::io::{BufReader, BufWriter, Result};
|
||||
use std::io::Error as IoError;
|
||||
use std::io::ErrorKind;
|
||||
use std::net::TcpStream;
|
||||
#[cfg(feature = "ssl")] use std::result::Result as StdResult;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
#[cfg(feature = "encode")] use encoding::{DecoderTrap, EncoderTrap, Encoding};
|
||||
#[cfg(feature = "encode")] use encoding::label::encoding_from_whatwg_label;
|
||||
use client::data::kinds::{IrcReader, IrcWriter};
|
||||
use client::data::kinds::{IrcRead, IrcWrite};
|
||||
use client::data::message::ToMessage;
|
||||
#[cfg(feature = "ssl")] use openssl::ssl::{SslContext, SslMethod, SslStream};
|
||||
#[cfg(feature = "ssl")] use openssl::ssl::error::SslError;
|
||||
|
||||
/// A thread-safe connection.
|
||||
#[stable]
|
||||
pub struct Connection<T: IrcReader, U: IrcWriter> {
|
||||
pub struct Connection<T: IrcRead, U: IrcWrite> {
|
||||
reader: Mutex<T>,
|
||||
writer: Mutex<U>,
|
||||
}
|
||||
|
||||
/// A Connection over a buffered NetStream.
|
||||
#[stable]
|
||||
pub type NetConnection = Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>>;
|
||||
pub type NetConnection = Connection<BufReader<NetStream>, BufWriter<NetStream>>;
|
||||
/// An internal type
|
||||
type NetReaderWriterPair = (BufferedReader<NetStream>, BufferedWriter<NetStream>);
|
||||
type NetReadWritePair = (BufReader<NetStream>, BufWriter<NetStream>);
|
||||
|
||||
#[stable]
|
||||
impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||
impl Connection<BufReader<NetStream>, BufWriter<NetStream>> {
|
||||
/// Creates a thread-safe TCP connection to the specified server.
|
||||
#[stable]
|
||||
pub fn connect(host: &str, port: u16) -> IoResult<NetConnection> {
|
||||
pub fn connect(host: &str, port: u16) -> Result<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> {
|
||||
fn connect_internal(host: &str, port: u16) -> Result<NetReadWritePair> {
|
||||
let socket = try!(TcpStream::connect(&format!("{}:{}", host, port)[..]));
|
||||
Ok((BufferedReader::new(NetStream::UnsecuredTcpStream(socket.clone())),
|
||||
BufferedWriter::new(NetStream::UnsecuredTcpStream(socket))))
|
||||
Ok((BufReader::new(NetStream::UnsecuredTcpStream(try!(socket.try_clone()))),
|
||||
BufWriter::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.
|
||||
#[stable]
|
||||
pub fn connect_ssl(host: &str, port: u16) -> IoResult<NetConnection> {
|
||||
pub fn connect_ssl(host: &str, port: u16) -> Result<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> {
|
||||
fn connect_ssl_internal(host: &str, port: u16) -> Result<NetReadWritePair> {
|
||||
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((BufferedReader::new(NetStream::SslTcpStream(ssl_socket.clone())),
|
||||
BufferedWriter::new(NetStream::SslTcpStream(ssl_socket))))
|
||||
Ok((BufReader::new(NetStream::SslTcpStream(try!(ssl_socket.try_clone()))),
|
||||
BufWriter::new(NetStream::SslTcpStream(ssl_socket))))
|
||||
}
|
||||
|
||||
/// Panics because SSL support is not compiled in.
|
||||
#[cfg(not(feature = "ssl"))]
|
||||
fn connect_ssl_internal(host: &str, port: u16) -> IoResult<NetReaderWriterPair> {
|
||||
fn connect_ssl_internal(host: &str, port: u16) -> Result<NetReadWritePair> {
|
||||
panic!("Cannot connect to {}:{} over SSL without compiling with SSL support.", host, port)
|
||||
}
|
||||
|
||||
/// Reconnects to the specified server, dropping the current connection.
|
||||
#[stable]
|
||||
pub fn reconnect(&self, host: &str, port: u16) -> IoResult<()> {
|
||||
pub fn reconnect(&self, host: &str, port: u16) -> Result<()> {
|
||||
let use_ssl = match self.reader.lock().unwrap().get_ref() {
|
||||
&NetStream::UnsecuredTcpStream(_) => false,
|
||||
#[cfg(feature = "ssl")]
|
||||
|
@ -85,18 +89,12 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
|||
|
||||
/// Sets the keepalive for the network stream.
|
||||
#[unstable = "Rust IO has not stabilized."]
|
||||
pub fn set_keepalive(&self, delay_in_seconds: Option<usize>) -> IoResult<()> {
|
||||
pub fn set_keepalive(&self, delay_in_seconds: Option<u32>) -> Result<()> {
|
||||
self.mod_stream(|tcp| tcp.set_keepalive(delay_in_seconds))
|
||||
}
|
||||
|
||||
/// Sets the timeout for the network stream.
|
||||
#[unstable = "Rust IO has not stabilized."]
|
||||
pub fn set_timeout(&self, timeout_ms: Option<u64>) {
|
||||
self.mod_stream(|tcp| Ok(tcp.set_timeout(timeout_ms))).unwrap(); // this cannot fail.
|
||||
}
|
||||
|
||||
/// Modifies the internal TcpStream using a function.
|
||||
fn mod_stream<F>(&self, f: F) -> IoResult<()> where F: FnOnce(&mut TcpStream) -> IoResult<()> {
|
||||
fn mod_stream<F>(&self, f: F) -> Result<()> where F: FnOnce(&mut TcpStream) -> Result<()> {
|
||||
match self.reader.lock().unwrap().get_mut() {
|
||||
&mut NetStream::UnsecuredTcpStream(ref mut tcp) => f(tcp),
|
||||
#[cfg(feature = "ssl")]
|
||||
|
@ -106,7 +104,7 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
|||
}
|
||||
|
||||
#[stable]
|
||||
impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||
impl<T: IrcRead, U: IrcWrite> Connection<T, U> {
|
||||
/// Creates a new connection from an IrcReader and an IrcWriter.
|
||||
#[stable]
|
||||
pub fn new(reader: T, writer: U) -> Connection<T, U> {
|
||||
|
@ -119,23 +117,19 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
|||
/// Sends a Message over this connection.
|
||||
#[stable]
|
||||
#[cfg(feature = "encode")]
|
||||
pub fn send<M: ToMessage>(&self, to_msg: M, encoding: &str) -> IoResult<()> {
|
||||
pub fn send<M: ToMessage>(&self, to_msg: M, encoding: &str) -> Result<()> {
|
||||
let encoding = match encoding_from_whatwg_label(encoding) {
|
||||
Some(enc) => enc,
|
||||
None => return Err(IoError {
|
||||
kind: IoErrorKind::InvalidInput,
|
||||
desc: "Failed to find decoder.",
|
||||
detail: Some(format!("Invalid decoder: {}", encoding))
|
||||
})
|
||||
None => return Err(IoError::new(ErrorKind::InvalidInput, "Failed to find encoder.",
|
||||
Some(format!("Invalid encoder: {}", encoding))))
|
||||
};
|
||||
let msg = to_msg.to_message();
|
||||
let data = match encoding.encode(&msg.into_string(), EncoderTrap::Replace) {
|
||||
Ok(data) => data,
|
||||
Err(data) => return Err(IoError {
|
||||
kind: IoErrorKind::InvalidInput,
|
||||
desc: "Failed to decode message.",
|
||||
detail: Some(format!("Failed to decode {} as {}.", data, encoding.name())),
|
||||
})
|
||||
Err(data) => return Err(IoError::new(
|
||||
ErrorKind::InvalidInput, "Failed to encode message.",
|
||||
Some(format!("Failed to encode {} as {}.", data, encoding.name()))
|
||||
))
|
||||
};
|
||||
let mut writer = self.writer.lock().unwrap();
|
||||
try!(writer.write_all(&data));
|
||||
|
@ -145,32 +139,28 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
|||
/// Sends a message over this connection.
|
||||
#[stable]
|
||||
#[cfg(not(feature = "encode"))]
|
||||
pub fn send<M: ToMessage>(&self, to_msg: M) -> IoResult<()> {
|
||||
pub fn send<M: ToMessage>(&self, to_msg: M) -> Result<()> {
|
||||
let mut writer = self.writer.lock().unwrap();
|
||||
try!(writer.write_str(&to_msg.to_message().into_string()));
|
||||
try!(writer.write_all(&to_msg.to_message().into_string().as_bytes()));
|
||||
writer.flush()
|
||||
}
|
||||
|
||||
/// Receives a single line from this connection.
|
||||
#[stable]
|
||||
#[cfg(feature = "encoding")]
|
||||
pub fn recv(&self, encoding: &str) -> IoResult<String> {
|
||||
pub fn recv(&self, encoding: &str) -> Result<String> {
|
||||
let encoding = match encoding_from_whatwg_label(encoding) {
|
||||
Some(enc) => enc,
|
||||
None => return Err(IoError {
|
||||
kind: IoErrorKind::InvalidInput,
|
||||
desc: "Failed to find decoder.",
|
||||
detail: Some(format!("Invalid decoder: {}", encoding))
|
||||
})
|
||||
None => return Err(IoError::new(ErrorKind::InvalidInput, "Failed to find decoder.",
|
||||
Some(format!("Invalid decoder: {}", encoding))))
|
||||
};
|
||||
self.reader.lock().unwrap().read_until(b'\n').and_then(|line|
|
||||
match encoding.decode(&line, DecoderTrap::Replace) {
|
||||
let mut buf = Vec::new();
|
||||
self.reader.lock().unwrap().read_until(b'\n', &mut buf).and_then(|_|
|
||||
match encoding.decode(&buf, DecoderTrap::Replace) {
|
||||
_ if buf.is_empty() => Err(IoError::new(ErrorKind::Other, "EOF", None)),
|
||||
Ok(data) => Ok(data),
|
||||
Err(data) => Err(IoError {
|
||||
kind: IoErrorKind::InvalidInput,
|
||||
desc: "Failed to decode message.",
|
||||
detail: Some(format!("Failed to decode {} as {}.", data, encoding.name())),
|
||||
})
|
||||
Err(data) => Err(IoError::new(ErrorKind::InvalidInput, "Failed to decode message.",
|
||||
Some(format!("Failed to decode {} as {}.", data, encoding.name()))))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -178,8 +168,14 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
|||
/// Receives a single line from this connection.
|
||||
#[stable]
|
||||
#[cfg(not(feature = "encoding"))]
|
||||
pub fn recv(&self) -> IoResult<String> {
|
||||
self.reader.lock().unwrap().read_line()
|
||||
pub fn recv(&self) -> Result<String> {
|
||||
let mut ret = String::new();
|
||||
try!(self.reader.lock().unwrap().read_line(&mut ret));
|
||||
if ret.is_empty() {
|
||||
Err(IoError::new(ErrorKind::Other, "EOF", None))
|
||||
} else {
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
/// Acquires the Reader lock.
|
||||
|
@ -195,16 +191,13 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts a Result<T, SslError> into an IoResult<T>.
|
||||
/// Converts a Result<T, SslError> into an Result<T>.
|
||||
#[cfg(feature = "ssl")]
|
||||
fn ssl_to_io<T>(res: Result<T, SslError>) -> IoResult<T> {
|
||||
fn ssl_to_io<T>(res: StdResult<T, SslError>) -> Result<T> {
|
||||
match res {
|
||||
Ok(x) => Ok(x),
|
||||
Err(e) => Err(IoError {
|
||||
kind: IoErrorKind::OtherIoError,
|
||||
desc: "An SSL error occurred.",
|
||||
detail: Some(e.description().to_owned()),
|
||||
}),
|
||||
Err(e) => Err(IoError::new(ErrorKind::Other, "An SSL error occurred.",
|
||||
Some(e.description().to_owned()))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,8 +214,8 @@ pub enum NetStream {
|
|||
SslTcpStream(SslStream<TcpStream>),
|
||||
}
|
||||
|
||||
impl Reader for NetStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
impl Read for NetStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
match self {
|
||||
&mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.read(buf),
|
||||
#[cfg(feature = "ssl")]
|
||||
|
@ -231,12 +224,20 @@ impl Reader for NetStream {
|
|||
}
|
||||
}
|
||||
|
||||
impl Writer for NetStream {
|
||||
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
impl Write for NetStream {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
match self {
|
||||
&mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.write_all(buf),
|
||||
&mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.write(buf),
|
||||
#[cfg(feature = "ssl")]
|
||||
&mut NetStream::SslTcpStream(ref mut stream) => stream.write_all(buf),
|
||||
&mut NetStream::SslTcpStream(ref mut stream) => stream.write(buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
match self {
|
||||
&mut NetStream::UnsecuredTcpStream(ref mut stream) => stream.flush(),
|
||||
#[cfg(feature = "ssl")]
|
||||
&mut NetStream::SslTcpStream(ref mut stream) => stream.flush(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,20 +245,20 @@ impl Writer for NetStream {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Connection;
|
||||
use std::old_io::{MemReader, MemWriter};
|
||||
use std::old_io::util::{NullReader, NullWriter};
|
||||
use std::io::{Cursor, sink};
|
||||
use client::data::message::Message;
|
||||
use client::test::buf_empty;
|
||||
#[cfg(feature = "encode")] use encoding::{DecoderTrap, Encoding};
|
||||
#[cfg(feature = "encode")] use encoding::all::{ISO_8859_15, UTF_8};
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "encode"))]
|
||||
fn send() {
|
||||
let conn = Connection::new(NullReader, MemWriter::new());
|
||||
let conn = Connection::new(buf_empty(), Vec::new());
|
||||
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.writer().to_vec()).unwrap();
|
||||
assert_eq!(&data[..], "PRIVMSG test :Testing!\r\n");
|
||||
}
|
||||
|
||||
|
@ -265,20 +266,20 @@ mod test {
|
|||
#[cfg(not(feature = "encode"))]
|
||||
fn send_str() {
|
||||
let exp = "PRIVMSG test :Testing!\r\n";
|
||||
let conn = Connection::new(NullReader, MemWriter::new());
|
||||
let conn = Connection::new(buf_empty(), Vec::new());
|
||||
assert!(conn.send(exp).is_ok());
|
||||
let data = String::from_utf8(conn.writer().get_ref().to_vec()).unwrap();
|
||||
let data = String::from_utf8(conn.writer().to_vec()).unwrap();
|
||||
assert_eq!(&data[..], exp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "encode")]
|
||||
fn send_utf8() {
|
||||
let conn = Connection::new(NullReader, MemWriter::new());
|
||||
let conn = Connection::new(buf_empty(), Vec::new());
|
||||
assert!(conn.send(
|
||||
Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("€ŠšŽžŒœŸ")), "UTF-8"
|
||||
).is_ok());
|
||||
let data = UTF_8.decode(conn.writer().get_ref(), DecoderTrap::Strict).unwrap();
|
||||
let data = UTF_8.decode(&conn.writer(), DecoderTrap::Strict).unwrap();
|
||||
assert_eq!(&data[..], "PRIVMSG test :€ŠšŽžŒœŸ\r\n");
|
||||
}
|
||||
|
||||
|
@ -286,20 +287,20 @@ mod test {
|
|||
#[cfg(feature = "encode")]
|
||||
fn send_utf8_str() {
|
||||
let exp = "PRIVMSG test :€ŠšŽžŒœŸ\r\n";
|
||||
let conn = Connection::new(NullReader, MemWriter::new());
|
||||
let conn = Connection::new(buf_empty(), Vec::new());
|
||||
assert!(conn.send(exp, "UTF-8").is_ok());
|
||||
let data = UTF_8.decode(conn.writer().get_ref(), DecoderTrap::Strict).unwrap();
|
||||
let data = UTF_8.decode(&conn.writer(), DecoderTrap::Strict).unwrap();
|
||||
assert_eq!(&data[..], exp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "encode")]
|
||||
fn send_iso885915() {
|
||||
let conn = Connection::new(NullReader, MemWriter::new());
|
||||
let conn = Connection::new(buf_empty(), Vec::new());
|
||||
assert!(conn.send(
|
||||
Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("€ŠšŽžŒœŸ")), "l9"
|
||||
).is_ok());
|
||||
let data = ISO_8859_15.decode(conn.writer().get_ref(), DecoderTrap::Strict).unwrap();
|
||||
let data = ISO_8859_15.decode(&conn.writer(), DecoderTrap::Strict).unwrap();
|
||||
assert_eq!(&data[..], "PRIVMSG test :€ŠšŽžŒœŸ\r\n");
|
||||
}
|
||||
|
||||
|
@ -307,9 +308,9 @@ mod test {
|
|||
#[cfg(feature = "encode")]
|
||||
fn send_iso885915_str() {
|
||||
let exp = "PRIVMSG test :€ŠšŽžŒœŸ\r\n";
|
||||
let conn = Connection::new(NullReader, MemWriter::new());
|
||||
let conn = Connection::new(buf_empty(), Vec::new());
|
||||
assert!(conn.send(exp, "l9").is_ok());
|
||||
let data = ISO_8859_15.decode(conn.writer().get_ref(), DecoderTrap::Strict).unwrap();
|
||||
let data = ISO_8859_15.decode(&conn.writer(), DecoderTrap::Strict).unwrap();
|
||||
assert_eq!(&data[..], exp);
|
||||
}
|
||||
|
||||
|
@ -317,7 +318,7 @@ mod test {
|
|||
#[cfg(not(feature = "encode"))]
|
||||
fn recv() {
|
||||
let conn = Connection::new(
|
||||
MemReader::new("PRIVMSG test :Testing!\r\n".as_bytes().to_vec()), NullWriter
|
||||
Cursor::new("PRIVMSG test :Testing!\r\n".as_bytes().to_vec()), sink()
|
||||
);
|
||||
assert_eq!(&conn.recv().unwrap()[..], "PRIVMSG test :Testing!\r\n");
|
||||
}
|
||||
|
@ -326,7 +327,7 @@ mod test {
|
|||
#[cfg(feature = "encode")]
|
||||
fn recv_utf8() {
|
||||
let conn = Connection::new(
|
||||
MemReader::new(b"PRIVMSG test :Testing!\r\n".to_vec()), NullWriter
|
||||
Cursor::new(b"PRIVMSG test :Testing!\r\n".to_vec()), sink()
|
||||
);
|
||||
assert_eq!(&conn.recv("UTF-8").unwrap()[..], "PRIVMSG test :Testing!\r\n");
|
||||
}
|
||||
|
@ -335,13 +336,13 @@ mod test {
|
|||
#[cfg(feature = "encode")]
|
||||
fn recv_iso885915() {
|
||||
let conn = Connection::new(
|
||||
MemReader::new({
|
||||
Cursor::new({
|
||||
let mut vec = Vec::new();
|
||||
vec.push_all(b"PRIVMSG test :");
|
||||
vec.push_all(&[0xA4, 0xA6, 0xA8, 0xB4, 0xB8, 0xBC, 0xBD, 0xBE]);
|
||||
vec.push_all(b"\r\n");
|
||||
vec
|
||||
}), NullWriter
|
||||
}), sink()
|
||||
);
|
||||
assert_eq!(&conn.recv("l9").unwrap()[..], "PRIVMSG test :€ŠšŽžŒœŸ\r\n");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! Enumeration of all available client commands.
|
||||
#![stable]
|
||||
use std::old_io::{InvalidInput, IoError, IoResult};
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
use std::result::Result as StdResult;
|
||||
use std::str::FromStr;
|
||||
use client::data::message::{Message, ToMessage};
|
||||
|
||||
|
@ -363,7 +364,7 @@ impl ToMessage for Command {
|
|||
impl Command {
|
||||
/// Converts a Message into a Command.
|
||||
#[stable]
|
||||
pub fn from_message(m: &Message) -> IoResult<Command> {
|
||||
pub fn from_message(m: &Message) -> Result<Command> {
|
||||
Ok(if let "PASS" = &m.command[..] {
|
||||
match m.suffix {
|
||||
Some(ref suffix) => {
|
||||
|
@ -1081,7 +1082,7 @@ impl Command {
|
|||
|
||||
/// Converts a potential Message result into a potential Command result.
|
||||
#[unstable = "This feature is still relatively new."]
|
||||
pub fn from_message_io(m: IoResult<Message>) -> IoResult<Command> {
|
||||
pub fn from_message_io(m: Result<Message>) -> Result<Command> {
|
||||
m.and_then(|msg| Command::from_message(&msg))
|
||||
}
|
||||
}
|
||||
|
@ -1137,7 +1138,7 @@ impl CapSubCommand {
|
|||
|
||||
impl FromStr for CapSubCommand {
|
||||
type Err = &'static str;
|
||||
fn from_str(s: &str) -> Result<CapSubCommand, &'static str> {
|
||||
fn from_str(s: &str) -> StdResult<CapSubCommand, &'static str> {
|
||||
match s {
|
||||
"LS" => Ok(CapSubCommand::LS),
|
||||
"LIST" => Ok(CapSubCommand::LIST),
|
||||
|
@ -1152,10 +1153,6 @@ impl FromStr for CapSubCommand {
|
|||
}
|
||||
|
||||
/// Produces an invalid_input IoError.
|
||||
fn invalid_input() -> IoError {
|
||||
IoError {
|
||||
kind: InvalidInput,
|
||||
desc: "Failed to parse malformed message as command.",
|
||||
detail: None
|
||||
}
|
||||
fn invalid_input() -> Error {
|
||||
Error::new(ErrorKind::InvalidInput, "Failed to parse malformed message as command.", None)
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
#![stable]
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::old_io::fs::File;
|
||||
use std::old_io::{InvalidInput, IoError, IoResult};
|
||||
use std::error::Error as StdError;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
use rustc_serialize::json::decode;
|
||||
|
||||
/// Configuration data.
|
||||
|
@ -64,19 +65,19 @@ pub struct Config {
|
|||
impl Config {
|
||||
/// Loads a JSON configuration from the desired path.
|
||||
#[stable]
|
||||
pub fn load(path: Path) -> IoResult<Config> {
|
||||
pub fn load(path: Path) -> Result<Config> {
|
||||
let mut file = try!(File::open(&path));
|
||||
let data = try!(file.read_to_string());
|
||||
decode(&data[..]).map_err(|e| IoError {
|
||||
kind: InvalidInput,
|
||||
desc: "Failed to decode configuration file.",
|
||||
detail: Some(e.description().to_owned()),
|
||||
})
|
||||
let mut data = String::new();
|
||||
try!(file.read_to_string(&mut data));
|
||||
decode(&data[..]).map_err(|e|
|
||||
Error::new(ErrorKind::InvalidInput, "Failed to decode configuration file.",
|
||||
Some(e.description().to_owned()))
|
||||
)
|
||||
}
|
||||
|
||||
/// Loads a JSON configuration using the string as a UTF-8 path.
|
||||
#[stable]
|
||||
pub fn load_utf8(path: &str) -> IoResult<Config> {
|
||||
pub fn load_utf8(path: &str) -> Result<Config> {
|
||||
Config::load(Path::new(path))
|
||||
}
|
||||
|
||||
|
|
|
@ -10,19 +10,16 @@ pub use client::data::user::{AccessLevel, User};
|
|||
pub mod kinds {
|
||||
//! Trait definitions of appropriate Writers and Buffers for use with this library.
|
||||
#![stable]
|
||||
use std::io::prelude::*;
|
||||
|
||||
/// Trait describing all possible Writers for this library.
|
||||
#[stable]
|
||||
pub trait IrcWriter: Writer + Sized + Send + 'static {}
|
||||
impl<T> IrcWriter for T where T: Writer + Sized + Send + 'static {}
|
||||
pub trait IrcWrite: Write + Sized + Send + 'static {}
|
||||
impl<T> IrcWrite for T where T: Write + Sized + Send + 'static {}
|
||||
/// Trait describing all possible Readers for this library.
|
||||
#[stable]
|
||||
pub trait IrcReader: Buffer + Sized + Send + 'static {}
|
||||
impl<T> IrcReader for T where T: Buffer + Sized + Send + 'static {}
|
||||
/// Trait describing all possible Streams for this library.
|
||||
#[unstable = "May be removed."]
|
||||
pub trait IrcStream: IrcWriter + IrcReader {}
|
||||
impl<T> IrcStream for T where T: IrcWriter + IrcReader {}
|
||||
pub trait IrcRead: BufRead + Sized + Send + 'static {}
|
||||
impl<T> IrcRead for T where T: BufRead + Sized + Send + 'static {}
|
||||
}
|
||||
|
||||
pub mod command;
|
||||
|
|
|
@ -12,5 +12,14 @@ pub mod prelude {
|
|||
pub use client::server::{IrcServer, Server};
|
||||
pub use client::server::utils::ServerExt;
|
||||
pub use client::data::{Command, Config, Message, Response, ToMessage};
|
||||
pub use client::data::kinds::{IrcReader, IrcWriter};
|
||||
pub use client::data::kinds::{IrcRead, IrcWrite};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use std::io::{BufReader, Empty, empty};
|
||||
|
||||
pub fn buf_empty() -> BufReader<Empty> {
|
||||
BufReader::new(empty())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
#![stable]
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::old_io::{BufferedReader, BufferedWriter, IoError, IoErrorKind, IoResult};
|
||||
use std::io::{BufReader, BufWriter, Error, ErrorKind, Result};
|
||||
use std::sync::{Mutex, RwLock};
|
||||
use std::iter::Map;
|
||||
use client::conn::{Connection, NetStream};
|
||||
use client::data::{Command, Config, Message, Response, User};
|
||||
use client::data::Command::{JOIN, NICK, NICKSERV, PONG, MODE};
|
||||
use client::data::kinds::{IrcReader, IrcWriter};
|
||||
use client::data::kinds::{IrcRead, IrcWrite};
|
||||
#[cfg(feature = "ctcp")] use time::now;
|
||||
|
||||
pub mod utils;
|
||||
|
@ -23,7 +23,7 @@ pub trait Server<'a, T, U> {
|
|||
fn config(&self) -> &Config;
|
||||
/// Sends a Command to this Server.
|
||||
#[stable]
|
||||
fn send(&self, command: Command) -> IoResult<()>;
|
||||
fn send(&self, command: Command) -> Result<()>;
|
||||
/// Gets an Iterator over Messages received by this Server.
|
||||
#[stable]
|
||||
fn iter(&'a self) -> ServerIterator<'a, T, U>;
|
||||
|
@ -38,7 +38,7 @@ pub trait Server<'a, T, U> {
|
|||
|
||||
/// A thread-safe implementation of an IRC Server connection.
|
||||
#[stable]
|
||||
pub struct IrcServer<T: IrcReader, U: IrcWriter> {
|
||||
pub struct IrcServer<T: IrcRead, U: IrcWrite> {
|
||||
/// The thread-safe IRC connection.
|
||||
conn: Connection<T, U>,
|
||||
/// The configuration used with this connection.
|
||||
|
@ -51,21 +51,21 @@ pub struct IrcServer<T: IrcReader, U: IrcWriter> {
|
|||
|
||||
/// An IrcServer over a buffered NetStream.
|
||||
#[stable]
|
||||
pub type NetIrcServer = IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>>;
|
||||
pub type NetIrcServer = IrcServer<BufReader<NetStream>, BufWriter<NetStream>>;
|
||||
|
||||
#[stable]
|
||||
impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||
impl IrcServer<BufReader<NetStream>, BufWriter<NetStream>> {
|
||||
/// Creates a new IRC Server connection from the configuration at the specified path,
|
||||
/// connecting immediately.
|
||||
#[stable]
|
||||
pub fn new(config: &str) -> IoResult<NetIrcServer> {
|
||||
pub fn new(config: &str) -> Result<NetIrcServer> {
|
||||
IrcServer::from_config(try!(Config::load_utf8(config)))
|
||||
}
|
||||
|
||||
/// Creates a new IRC server connection from the specified configuration, connecting
|
||||
/// immediately.
|
||||
#[stable]
|
||||
pub fn from_config(config: Config) -> IoResult<NetIrcServer> {
|
||||
pub fn from_config(config: Config) -> Result<NetIrcServer> {
|
||||
let conn = try!(if config.use_ssl() {
|
||||
Connection::connect_ssl(config.server(), config.port())
|
||||
} else {
|
||||
|
@ -77,23 +77,23 @@ impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
|||
|
||||
/// Reconnects to the IRC server.
|
||||
#[stable]
|
||||
pub fn reconnect(&self) -> IoResult<()> {
|
||||
pub fn reconnect(&self) -> Result<()> {
|
||||
self.conn.reconnect(self.config().server(), self.config.port())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: IrcReader, U: IrcWriter> Server<'a, T, U> for IrcServer<T, U> {
|
||||
impl<'a, T: IrcRead, U: IrcWrite> Server<'a, T, U> for IrcServer<T, U> {
|
||||
fn config(&self) -> &Config {
|
||||
&self.config
|
||||
}
|
||||
|
||||
#[cfg(feature = "encode")]
|
||||
fn send(&self, cmd: Command) -> IoResult<()> {
|
||||
fn send(&self, cmd: Command) -> Result<()> {
|
||||
self.conn.send(cmd, self.config.encoding())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "encode"))]
|
||||
fn send(&self, cmd: Command) -> IoResult<()> {
|
||||
fn send(&self, cmd: Command) -> Result<()> {
|
||||
self.conn.send(cmd)
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Server<'a, T, U> for IrcServer<T, U> {
|
|||
}
|
||||
|
||||
#[stable]
|
||||
impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||
impl<T: IrcRead, U: IrcWrite> IrcServer<T, U> {
|
||||
/// Creates an IRC server from the specified configuration, and any arbitrary Connection.
|
||||
#[stable]
|
||||
pub fn from_connection(config: Config, conn: Connection<T, U>) -> IrcServer<T, U> {
|
||||
|
@ -264,16 +264,16 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
|||
|
||||
/// An Iterator over an IrcServer's incoming Messages.
|
||||
#[stable]
|
||||
pub struct ServerIterator<'a, T: IrcReader, U: IrcWriter> {
|
||||
pub struct ServerIterator<'a, T: IrcRead, U: IrcWrite> {
|
||||
server: &'a IrcServer<T, U>
|
||||
}
|
||||
|
||||
/// An Iterator over an IrcServer's incoming Commands.
|
||||
pub type ServerCmdIterator<'a, T, U> =
|
||||
Map<ServerIterator<'a, T, U>, fn(IoResult<Message>) -> IoResult<Command>>;
|
||||
Map<ServerIterator<'a, T, U>, fn(Result<Message>) -> Result<Command>>;
|
||||
|
||||
#[unstable = "Design is liable to change to accomodate new functionality."]
|
||||
impl<'a, T: IrcReader, U: IrcWriter> ServerIterator<'a, T, U> {
|
||||
impl<'a, T: IrcRead, U: IrcWrite> ServerIterator<'a, T, U> {
|
||||
/// Creates a new ServerIterator for the desired IrcServer.
|
||||
#[unstable = "Design is liable to change to accomodate new functionality."]
|
||||
pub fn new(server: &IrcServer<T, U>) -> ServerIterator<T, U> {
|
||||
|
@ -282,36 +282,35 @@ impl<'a, T: IrcReader, U: IrcWriter> ServerIterator<'a, T, U> {
|
|||
|
||||
/// Gets the next line from the connection.
|
||||
#[cfg(feature = "encode")]
|
||||
fn get_next_line(&self) -> IoResult<String> {
|
||||
fn get_next_line(&self) -> Result<String> {
|
||||
self.server.conn.recv(self.server.config.encoding())
|
||||
}
|
||||
|
||||
/// Gets the next line from the connection.
|
||||
#[cfg(not(feature = "encode"))]
|
||||
fn get_next_line(&self) -> IoResult<String> {
|
||||
fn get_next_line(&self) -> Result<String> {
|
||||
self.server.conn.recv()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: IrcReader, U: IrcWriter> Iterator for ServerIterator<'a, T, U> {
|
||||
impl<'a, T: IrcRead, U: IrcWrite> Iterator for ServerIterator<'a, T, U> {
|
||||
#[stable]
|
||||
type Item = IoResult<Message>;
|
||||
fn next(&mut self) -> Option<IoResult<Message>> {
|
||||
type Item = Result<Message>;
|
||||
fn next(&mut self) -> Option<Result<Message>> {
|
||||
let res = self.get_next_line().and_then(|msg|
|
||||
match msg.parse() {
|
||||
Ok(msg) => {
|
||||
self.server.handle_message(&msg);
|
||||
Ok(msg)
|
||||
},
|
||||
Err(m) => Err(IoError {
|
||||
kind: IoErrorKind::InvalidInput,
|
||||
desc: "Failed to parse message.",
|
||||
detail: Some(format!("{} (Message: {})", m, msg))
|
||||
})
|
||||
Err(m) => Err(Error::new(ErrorKind::InvalidInput, "Failed to parse message.",
|
||||
Some(format!("{} (Message: {})", m, msg))))
|
||||
}
|
||||
);
|
||||
match res {
|
||||
Err(ref err) if err.kind == IoErrorKind::EndOfFile => None,
|
||||
Err(ref err) if err.kind() == ErrorKind::ConnectionAborted => None,
|
||||
Err(ref err) if err.kind() == ErrorKind::ConnectionReset => None,
|
||||
Err(ref err) if err.description() == "EOF" => None,
|
||||
_ => Some(res)
|
||||
}
|
||||
}
|
||||
|
@ -321,13 +320,13 @@ impl<'a, T: IrcReader, U: IrcWriter> Iterator for ServerIterator<'a, T, U> {
|
|||
mod test {
|
||||
use super::{IrcServer, Server};
|
||||
use std::default::Default;
|
||||
use std::old_io::MemReader;
|
||||
use std::old_io::util::{NullReader, NullWriter};
|
||||
use std::io::{Cursor, sink};
|
||||
use client::conn::Connection;
|
||||
use client::data::{Config, User};
|
||||
use client::data::command::Command::PRIVMSG;
|
||||
use client::data::kinds::IrcReader;
|
||||
use client::data::kinds::IrcRead;
|
||||
use client::data::message::ToMessage;
|
||||
use client::test::buf_empty;
|
||||
|
||||
pub fn test_config() -> Config {
|
||||
Config {
|
||||
|
@ -341,7 +340,7 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_server_value<T: IrcReader>(server: IrcServer<T, Vec<u8>>) -> String {
|
||||
pub fn get_server_value<T: IrcRead>(server: IrcServer<T, Vec<u8>>) -> String {
|
||||
let vec = server.conn().writer().clone();
|
||||
String::from_utf8(vec).unwrap()
|
||||
}
|
||||
|
@ -351,7 +350,7 @@ mod test {
|
|||
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(), Connection::new(
|
||||
MemReader::new(exp.as_bytes().to_vec()), NullWriter
|
||||
Cursor::new(exp.as_bytes().to_vec()), sink()
|
||||
));
|
||||
let mut messages = String::new();
|
||||
for message in server.iter() {
|
||||
|
@ -365,7 +364,7 @@ mod test {
|
|||
let exp = "PRIVMSG test :Hi!\r\nPRIVMSG test :This is a test!\r\n\
|
||||
JOIN #test\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(exp.as_bytes().to_vec()), NullWriter
|
||||
Cursor::new(exp.as_bytes().to_vec()), sink()
|
||||
));
|
||||
let mut messages = String::new();
|
||||
for command in server.iter_cmd() {
|
||||
|
@ -378,7 +377,7 @@ mod test {
|
|||
fn handle_message() {
|
||||
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(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -395,7 +394,7 @@ mod test {
|
|||
channels: Some(vec![format!("#test"), format!("#test2")]),
|
||||
.. Default::default()
|
||||
}, Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -413,7 +412,7 @@ mod test {
|
|||
channels: Some(vec![format!("#test"), format!("#test2")]),
|
||||
.. Default::default()
|
||||
}, Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -426,7 +425,7 @@ mod test {
|
|||
fn nickname_in_use() {
|
||||
let value = ":irc.pdgn.co 433 * test :Nickname is already in use.";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -440,7 +439,7 @@ mod test {
|
|||
let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\
|
||||
:irc.pdgn.co 433 * test2 :Nickname is already in use.\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -450,7 +449,7 @@ mod test {
|
|||
#[test]
|
||||
fn send() {
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
NullReader, Vec::new()
|
||||
buf_empty(), Vec::new()
|
||||
));
|
||||
assert!(server.send(PRIVMSG(format!("#test"), format!("Hi there!"))).is_ok());
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG #test :Hi there!\r\n");
|
||||
|
@ -461,7 +460,7 @@ mod test {
|
|||
fn user_tracking_names() {
|
||||
let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), NullWriter
|
||||
Cursor::new(value.as_bytes().to_vec()), sink()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -476,7 +475,7 @@ mod test {
|
|||
let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n\
|
||||
:test2!test@test JOIN #test\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), NullWriter
|
||||
Cursor::new(value.as_bytes().to_vec()), sink()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -491,7 +490,7 @@ mod test {
|
|||
let value = ":irc.test.net 353 test = #test :test ~owner &admin\r\n\
|
||||
:owner!test@test PART #test\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), NullWriter
|
||||
Cursor::new(value.as_bytes().to_vec()), sink()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -506,7 +505,7 @@ mod test {
|
|||
let value = ":irc.test.net 353 test = #test :+test ~owner &admin\r\n\
|
||||
:test!test@test MODE #test +o test\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), NullWriter
|
||||
Cursor::new(value.as_bytes().to_vec()), sink()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -529,7 +528,7 @@ mod test {
|
|||
fn finger_response() {
|
||||
let value = ":test!test@test PRIVMSG test :\u{001}FINGER\u{001}\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -543,7 +542,7 @@ mod test {
|
|||
fn version_response() {
|
||||
let value = ":test!test@test PRIVMSG test :\u{001}VERSION\u{001}\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -557,7 +556,7 @@ mod test {
|
|||
fn source_response() {
|
||||
let value = ":test!test@test PRIVMSG test :\u{001}SOURCE\u{001}\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -572,7 +571,7 @@ mod test {
|
|||
fn ctcp_ping_response() {
|
||||
let value = ":test!test@test PRIVMSG test :\u{001}PING test\u{001}\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -585,7 +584,7 @@ mod test {
|
|||
fn time_response() {
|
||||
let value = ":test!test@test PRIVMSG test :\u{001}TIME\u{001}\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
@ -600,7 +599,7 @@ mod test {
|
|||
fn user_info_response() {
|
||||
let value = ":test!test@test PRIVMSG test :\u{001}USERINFO\u{001}\r\n";
|
||||
let server = IrcServer::from_connection(test_config(), Connection::new(
|
||||
MemReader::new(value.as_bytes().to_vec()), Vec::new()
|
||||
Cursor::new(value.as_bytes().to_vec()), Vec::new()
|
||||
));
|
||||
for message in server.iter() {
|
||||
println!("{:?}", message);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
//! Utilities and shortcuts for working with IRC servers.
|
||||
#![stable]
|
||||
|
||||
use std::old_io::IoResult;
|
||||
use std::io::Result;
|
||||
use std::borrow::ToOwned;
|
||||
use client::data::Command::{CAP, INVITE, JOIN, KICK, KILL, MODE, NICK, NOTICE};
|
||||
use client::data::Command::{OPER, PASS, PONG, PRIVMSG, QUIT, SAMODE, SANICK, TOPIC, USER};
|
||||
use client::data::command::CapSubCommand::{END, REQ};
|
||||
use client::data::kinds::{IrcReader, IrcWriter};
|
||||
use client::data::kinds::{IrcRead, IrcWrite};
|
||||
#[cfg(feature = "ctcp")] use time::get_time;
|
||||
use client::server::Server;
|
||||
|
||||
|
@ -15,7 +15,7 @@ use client::server::Server;
|
|||
pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
||||
/// Sends a NICK and USER to identify.
|
||||
#[unstable = "Capabilities requests may be moved outside of identify."]
|
||||
fn identify(&self) -> IoResult<()> {
|
||||
fn identify(&self) -> Result<()> {
|
||||
// We'll issue a CAP REQ for multi-prefix support to improve access level tracking.
|
||||
try!(self.send(CAP(None, REQ, None, Some("multi-prefix".to_owned()))));
|
||||
try!(self.send(CAP(None, END, None, None))); // Then, send a CAP END to end the negotiation.
|
||||
|
@ -30,25 +30,25 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
|
||||
/// Sends a PONG with the specified message.
|
||||
#[stable]
|
||||
fn send_pong(&self, msg: &str) -> IoResult<()> {
|
||||
fn send_pong(&self, msg: &str) -> Result<()> {
|
||||
self.send(PONG(msg.to_owned(), None))
|
||||
}
|
||||
|
||||
/// Joins the specified channel or chanlist.
|
||||
#[stable]
|
||||
fn send_join(&self, chanlist: &str) -> IoResult<()> {
|
||||
fn send_join(&self, chanlist: &str) -> Result<()> {
|
||||
self.send(JOIN(chanlist.to_owned(), None))
|
||||
}
|
||||
|
||||
/// Attempts to oper up using the specified username and password.
|
||||
#[stable]
|
||||
fn send_oper(&self, username: &str, password: &str) -> IoResult<()> {
|
||||
fn send_oper(&self, username: &str, password: &str) -> Result<()> {
|
||||
self.send(OPER(username.to_owned(), password.to_owned()))
|
||||
}
|
||||
|
||||
/// Sends a message to the specified target.
|
||||
#[stable]
|
||||
fn send_privmsg(&self, target: &str, message: &str) -> IoResult<()> {
|
||||
fn send_privmsg(&self, target: &str, message: &str) -> Result<()> {
|
||||
for line in message.split("\r\n") {
|
||||
try!(self.send(PRIVMSG(target.to_owned(), line.to_owned())))
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
|
||||
/// Sends a notice to the specified target.
|
||||
#[stable]
|
||||
fn send_notice(&self, target: &str, message: &str) -> IoResult<()> {
|
||||
fn send_notice(&self, target: &str, message: &str) -> Result<()> {
|
||||
for line in message.split("\r\n") {
|
||||
try!(self.send(NOTICE(target.to_owned(), line.to_owned())))
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// Sets the topic of a channel or requests the current one.
|
||||
/// If `topic` is an empty string, it won't be included in the message.
|
||||
#[unstable = "Design may change."]
|
||||
fn send_topic(&self, channel: &str, topic: &str) -> IoResult<()> {
|
||||
fn send_topic(&self, channel: &str, topic: &str) -> Result<()> {
|
||||
self.send(TOPIC(channel.to_owned(), if topic.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
|
@ -77,14 +77,14 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
|
||||
/// Kills the target with the provided message.
|
||||
#[stable]
|
||||
fn send_kill(&self, target: &str, message: &str) -> IoResult<()> {
|
||||
fn send_kill(&self, target: &str, message: &str) -> Result<()> {
|
||||
self.send(KILL(target.to_owned(), message.to_owned()))
|
||||
}
|
||||
|
||||
/// Kicks the listed nicknames from the listed channels with a comment.
|
||||
/// If `message` is an empty string, it won't be included in the message.
|
||||
#[unstable = "Design may change."]
|
||||
fn send_kick(&self, chanlist: &str, nicklist: &str, message: &str) -> IoResult<()> {
|
||||
fn send_kick(&self, chanlist: &str, nicklist: &str, message: &str) -> Result<()> {
|
||||
self.send(KICK(chanlist.to_owned(), nicklist.to_owned(), if message.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
|
@ -95,7 +95,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// Changes the mode of the target.
|
||||
/// If `modeparmas` is an empty string, it won't be included in the message.
|
||||
#[unstable = "Design may change."]
|
||||
fn send_mode(&self, target: &str, mode: &str, modeparams: &str) -> IoResult<()> {
|
||||
fn send_mode(&self, target: &str, mode: &str, modeparams: &str) -> Result<()> {
|
||||
self.send(MODE(target.to_owned(), mode.to_owned(), if modeparams.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
|
@ -106,7 +106,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// Changes the mode of the target by force.
|
||||
/// If `modeparams` is an empty string, it won't be included in the message.
|
||||
#[unstable = "Design may change."]
|
||||
fn send_samode(&self, target: &str, mode: &str, modeparams: &str) -> IoResult<()> {
|
||||
fn send_samode(&self, target: &str, mode: &str, modeparams: &str) -> Result<()> {
|
||||
self.send(SAMODE(target.to_owned(), mode.to_owned(), if modeparams.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
|
@ -116,20 +116,20 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
|
||||
/// Forces a user to change from the old nickname to the new nickname.
|
||||
#[stable]
|
||||
fn send_sanick(&self, old_nick: &str, new_nick: &str) -> IoResult<()> {
|
||||
fn send_sanick(&self, old_nick: &str, new_nick: &str) -> Result<()> {
|
||||
self.send(SANICK(old_nick.to_owned(), new_nick.to_owned()))
|
||||
}
|
||||
|
||||
/// Invites a user to the specified channel.
|
||||
#[stable]
|
||||
fn send_invite(&self, nick: &str, chan: &str) -> IoResult<()> {
|
||||
fn send_invite(&self, nick: &str, chan: &str) -> Result<()> {
|
||||
self.send(INVITE(nick.to_owned(), chan.to_owned()))
|
||||
}
|
||||
|
||||
/// Quits the server entirely with a message.
|
||||
/// This defaults to `Powered by Rust.` if none is specified.
|
||||
#[unstable = "Design may change."]
|
||||
fn send_quit(&self, msg: &str) -> IoResult<()> {
|
||||
fn send_quit(&self, msg: &str) -> Result<()> {
|
||||
self.send(QUIT(Some(if msg.len() == 0 {
|
||||
"Powered by Rust.".to_owned()
|
||||
} else {
|
||||
|
@ -141,7 +141,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_ctcp(&self, target: &str, msg: &str) -> IoResult<()> {
|
||||
fn send_ctcp(&self, target: &str, msg: &str) -> Result<()> {
|
||||
self.send_privmsg(target, &format!("\u{001}{}\u{001}", msg)[..])
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_action(&self, target: &str, msg: &str) -> IoResult<()> {
|
||||
fn send_action(&self, target: &str, msg: &str) -> Result<()> {
|
||||
self.send_ctcp(target, &format!("ACTION {}", msg)[..])
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_finger(&self, target: &str) -> IoResult<()> {
|
||||
fn send_finger(&self, target: &str) -> Result<()> {
|
||||
self.send_ctcp(target, "FINGER")
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_version(&self, target: &str) -> IoResult<()> {
|
||||
fn send_version(&self, target: &str) -> Result<()> {
|
||||
self.send_ctcp(target, "VERSION")
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_source(&self, target: &str) -> IoResult<()> {
|
||||
fn send_source(&self, target: &str) -> Result<()> {
|
||||
self.send_ctcp(target, "SOURCE")
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_user_info(&self, target: &str) -> IoResult<()> {
|
||||
fn send_user_info(&self, target: &str) -> Result<()> {
|
||||
self.send_ctcp(target, "USERINFO")
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_ctcp_ping(&self, target: &str) -> IoResult<()> {
|
||||
fn send_ctcp_ping(&self, target: &str) -> Result<()> {
|
||||
let time = get_time();
|
||||
self.send_ctcp(target, &format!("PING {}.{}", time.sec, time.nsec)[..])
|
||||
}
|
||||
|
@ -198,27 +198,27 @@ pub trait ServerExt<'a, T, U>: Server<'a, T, U> {
|
|||
/// This requires the CTCP feature to be enabled.
|
||||
#[stable]
|
||||
#[cfg(feature = "ctcp")]
|
||||
fn send_time(&self, target: &str) -> IoResult<()> {
|
||||
fn send_time(&self, target: &str) -> Result<()> {
|
||||
self.send_ctcp(target, "TIME")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: IrcReader, U: IrcWriter, K: Server<'a, T, U>> ServerExt<'a, T, U> for K {}
|
||||
impl<'a, T: IrcRead, U: IrcWrite, K: Server<'a, T, U>> ServerExt<'a, T, U> for K {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::ServerExt;
|
||||
use std::default::Default;
|
||||
use std::old_io::util::NullReader;
|
||||
use client::conn::Connection;
|
||||
use client::data::Config;
|
||||
use client::server::IrcServer;
|
||||
use client::server::test::{get_server_value, test_config};
|
||||
use client::test::buf_empty;
|
||||
|
||||
#[test]
|
||||
fn identify() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.identify().unwrap();
|
||||
assert_eq!(&get_server_value(server)[..],
|
||||
"CAP REQ :multi-prefix\r\nCAP END\r\nNICK :test\r\nUSER test 0 * :test\r\n");
|
||||
|
@ -230,7 +230,7 @@ mod test {
|
|||
nickname: Some(format!("test")),
|
||||
password: Some(format!("password")),
|
||||
.. Default::default()
|
||||
}, Connection::new(NullReader, Vec::new()));
|
||||
}, Connection::new(buf_empty(), Vec::new()));
|
||||
server.identify().unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "CAP REQ :multi-prefix\r\nCAP END\r\n\
|
||||
PASS :password\r\nNICK :test\r\nUSER test 0 * :test\r\n");
|
||||
|
@ -239,7 +239,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_pong() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_pong("irc.test.net").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PONG :irc.test.net\r\n");
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_join() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_join("#test,#test2,#test3").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "JOIN #test,#test2,#test3\r\n");
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_oper() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_oper("test", "test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "OPER test :test\r\n");
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_privmsg() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_privmsg("#test", "Hi, everybody!").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG #test :Hi, everybody!\r\n");
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_notice() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_notice("#test", "Hi, everybody!").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "NOTICE #test :Hi, everybody!\r\n");
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_topic_no_topic() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_topic("#test", "").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "TOPIC #test\r\n");
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_topic() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_topic("#test", "Testing stuff.").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "TOPIC #test :Testing stuff.\r\n");
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_kill() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_kill("test", "Testing kills.").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "KILL test :Testing kills.\r\n");
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_kick_no_message() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_kick("#test", "test", "").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "KICK #test test\r\n");
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_kick() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_kick("#test", "test", "Testing kicks.").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "KICK #test test :Testing kicks.\r\n");
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_mode_no_modeparams() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_mode("#test", "+i", "").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "MODE #test +i\r\n");
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_mode() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_mode("#test", "+o", "test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "MODE #test +o test\r\n");
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_samode_no_modeparams() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_samode("#test", "+i", "").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "SAMODE #test +i\r\n");
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_samode() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_samode("#test", "+o", "test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "SAMODE #test +o test\r\n");
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_sanick() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_sanick("test", "test2").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "SANICK test test2\r\n");
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ mod test {
|
|||
#[test]
|
||||
fn send_invite() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_invite("test", "#test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "INVITE test #test\r\n");
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_ctcp() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_ctcp("test", "MESSAGE").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}MESSAGE\u{001}\r\n");
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_action() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_action("test", "tests.").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}ACTION tests.\u{001}\r\n");
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_finger() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_finger("test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}FINGER\u{001}\r\n");
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_version() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_version("test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}VERSION\u{001}\r\n");
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_source() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_source("test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}SOURCE\u{001}\r\n");
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_user_info() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_user_info("test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}USERINFO\u{001}\r\n");
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_ctcp_ping() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_ctcp_ping("test").unwrap();
|
||||
let val = get_server_value(server);
|
||||
println!("{}", val);
|
||||
|
@ -434,7 +434,7 @@ mod test {
|
|||
#[cfg(feature = "ctcp")]
|
||||
fn send_time() {
|
||||
let server = IrcServer::from_connection(test_config(),
|
||||
Connection::new(NullReader, Vec::new()));
|
||||
Connection::new(buf_empty(), Vec::new()));
|
||||
server.send_time("test").unwrap();
|
||||
assert_eq!(&get_server_value(server)[..], "PRIVMSG test :\u{001}TIME\u{001}\r\n");
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#![unstable]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
#![feature(collections, core, io, old_io, old_path)]
|
||||
#![feature(collections, core, fs, io, net, old_path)]
|
||||
#[cfg(feature = "ctcp")] extern crate time;
|
||||
#[cfg(feature = "encode")] extern crate encoding;
|
||||
extern crate "rustc-serialize" as rustc_serialize;
|
||||
|
|
Loading…
Add table
Reference in a new issue