Merge pull request #11 from SBSTP/tomessage
[API Improvement] Implement ToMessage for Command and Message and use ToMessage in Connection
This commit is contained in:
commit
202748e7a9
4 changed files with 63 additions and 40 deletions
20
src/conn.rs
20
src/conn.rs
|
@ -6,7 +6,7 @@ use std::io::{BufferedReader, BufferedWriter, IoResult, TcpStream};
|
||||||
#[cfg(feature = "encode")] use encoding::{DecoderTrap, EncoderTrap, Encoding};
|
#[cfg(feature = "encode")] use encoding::{DecoderTrap, EncoderTrap, Encoding};
|
||||||
#[cfg(feature = "encode")] use encoding::label::encoding_from_whatwg_label;
|
#[cfg(feature = "encode")] use encoding::label::encoding_from_whatwg_label;
|
||||||
use data::kinds::{IrcReader, IrcWriter};
|
use data::kinds::{IrcReader, IrcWriter};
|
||||||
use data::message::Message;
|
use data::message::ToMessage;
|
||||||
#[cfg(feature = "ssl")] use openssl::ssl::{SslContext, SslMethod, SslStream};
|
#[cfg(feature = "ssl")] use openssl::ssl::{SslContext, SslMethod, SslStream};
|
||||||
#[cfg(feature = "ssl")] use openssl::ssl::error::SslError;
|
#[cfg(feature = "ssl")] use openssl::ssl::error::SslError;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ type NetReaderWriterPair = (BufferedReader<NetStream>, BufferedWriter<NetStream>
|
||||||
impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
/// 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<NetConnection> {
|
pub fn connect(host: &str, port: u16) -> IoResult<NetConnection> {
|
||||||
let (reader, writer) = try!(Connection::connect_internal(host, port));
|
let (reader, writer) = try!(Connection::connect_internal(host, port));
|
||||||
Ok(Connection::new(reader, writer))
|
Ok(Connection::new(reader, writer))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<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(SslMethod::Tlsv1)));
|
let ssl = try!(ssl_to_io(SslContext::new(SslMethod::Tlsv1)));
|
||||||
let ssl_socket = try!(ssl_to_io(SslStream::new(&ssl, socket)));
|
let ssl_socket = try!(ssl_to_io(SslStream::new(&ssl, socket)));
|
||||||
Ok((BufferedReader::new(NetStream::SslTcpStream(ssl_socket.clone())),
|
Ok((BufferedReader::new(NetStream::SslTcpStream(ssl_socket.clone())),
|
||||||
BufferedWriter::new(NetStream::SslTcpStream(ssl_socket))))
|
BufferedWriter::new(NetStream::SslTcpStream(ssl_socket))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,13 +78,13 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
*self.writer.lock() = writer;
|
*self.writer.lock() = writer;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the keepalive for the network stream.
|
/// Sets the keepalive for the network stream.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn set_keepalive(&self, delay_in_seconds: Option<uint>) -> IoResult<()> {
|
pub fn set_keepalive(&self, delay_in_seconds: Option<uint>) -> IoResult<()> {
|
||||||
self.mod_stream(|tcp| tcp.set_keepalive(delay_in_seconds))
|
self.mod_stream(|tcp| tcp.set_keepalive(delay_in_seconds))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the timeout for the network stream.
|
/// Sets the timeout for the network stream.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn set_timeout(&self, timeout_ms: Option<u64>) {
|
pub fn set_timeout(&self, timeout_ms: Option<u64>) {
|
||||||
|
@ -114,7 +114,8 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
/// Sends a Message over this connection.
|
/// Sends a Message over this connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[cfg(feature = "encode")]
|
#[cfg(feature = "encode")]
|
||||||
pub fn send(&self, message: Message, encoding: &str) -> IoResult<()> {
|
pub fn send<T: ToMessage>(&self, tomsg: T, encoding: &str) -> IoResult<()> {
|
||||||
|
let message = tomsg.to_message();
|
||||||
let encoding = match encoding_from_whatwg_label(encoding) {
|
let encoding = match encoding_from_whatwg_label(encoding) {
|
||||||
Some(enc) => enc,
|
Some(enc) => enc,
|
||||||
None => return Err(IoError {
|
None => return Err(IoError {
|
||||||
|
@ -139,7 +140,8 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
/// Sends a message over this connection.
|
/// Sends a message over this connection.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[cfg(not(feature = "encode"))]
|
#[cfg(not(feature = "encode"))]
|
||||||
pub fn send(&self, message: Message) -> IoResult<()> {
|
pub fn send<T: ToMessage>(&self, tomsg: T) -> IoResult<()> {
|
||||||
|
let message = tomsg.to_message();
|
||||||
let mut writer = self.writer.lock();
|
let mut writer = self.writer.lock();
|
||||||
try!(writer.write_str(message.into_string()[]));
|
try!(writer.write_str(message.into_string()[]));
|
||||||
writer.flush()
|
writer.flush()
|
||||||
|
@ -181,7 +183,7 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
pub fn reader<'a>(&'a self) -> MutexGuard<'a, T> {
|
pub fn reader<'a>(&'a self) -> MutexGuard<'a, T> {
|
||||||
self.reader.lock()
|
self.reader.lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquires the Writer lock.
|
/// Acquires the Writer lock.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn writer<'a>(&'a self) -> MutexGuard<'a, U> {
|
pub fn writer<'a>(&'a self) -> MutexGuard<'a, U> {
|
||||||
|
@ -261,7 +263,7 @@ mod test {
|
||||||
Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("€ŠšŽžŒœŸ")), "UTF-8"
|
Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("€ŠšŽžŒœŸ")), "UTF-8"
|
||||||
).is_ok());
|
).is_ok());
|
||||||
let data = UTF_8.decode(conn.writer().get_ref(), DecoderTrap::Strict).unwrap();
|
let data = UTF_8.decode(conn.writer().get_ref(), DecoderTrap::Strict).unwrap();
|
||||||
assert_eq!(data[], "PRIVMSG test :€ŠšŽžŒœŸ\r\n");
|
assert_eq!(data[], "PRIVMSG test :€ŠšŽžŒœŸ\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
#![stable]
|
#![stable]
|
||||||
use std::io::{InvalidInput, IoError, IoResult};
|
use std::io::{InvalidInput, IoError, IoResult};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use data::message::Message;
|
use data::message::{Message, ToMessage};
|
||||||
|
|
||||||
/// List of all client commands as defined in [RFC 2812](http://tools.ietf.org/html/rfc2812). This
|
/// List of all client commands as defined in [RFC 2812](http://tools.ietf.org/html/rfc2812). This
|
||||||
/// also includes commands from the
|
/// also includes commands from the
|
||||||
/// [capabilities extension](https://tools.ietf.org/html/draft-mitchell-irc-capabilities-01).
|
/// [capabilities extension](https://tools.ietf.org/html/draft-mitchell-irc-capabilities-01).
|
||||||
/// Additionally, this includes some common additional commands from popular IRCds.
|
/// Additionally, this includes some common additional commands from popular IRCds.
|
||||||
#[stable]
|
#[stable]
|
||||||
|
@ -144,17 +144,18 @@ pub enum Command<'a> {
|
||||||
HOSTSERV(&'a str),
|
HOSTSERV(&'a str),
|
||||||
/// MEMOSERV message
|
/// MEMOSERV message
|
||||||
MEMOSERV(&'a str),
|
MEMOSERV(&'a str),
|
||||||
|
|
||||||
// Capabilities extension to IRCv3
|
// Capabilities extension to IRCv3
|
||||||
/// CAP COMMAND [param]
|
/// CAP COMMAND [param]
|
||||||
CAP(CapSubCommand, Option<&'a str>),
|
CAP(CapSubCommand, Option<&'a str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Command<'a> {
|
impl<'a> ToMessage for Command<'a> {
|
||||||
|
|
||||||
/// Converts a Command into a Message.
|
/// Converts a Command into a Message.
|
||||||
#[stable]
|
#[stable]
|
||||||
pub fn to_message(self) -> Message {
|
fn to_message(&self) -> Message {
|
||||||
match self {
|
match *self {
|
||||||
Command::PASS(p) => Message::new(None, "PASS", None, Some(p)),
|
Command::PASS(p) => Message::new(None, "PASS", None, Some(p)),
|
||||||
Command::NICK(n) => Message::new(None, "NICK", None, Some(n)),
|
Command::NICK(n) => Message::new(None, "NICK", None, Some(n)),
|
||||||
Command::USER(u, m, r) => Message::new(None, "USER", Some(vec![u, m, "*"]), Some(r)),
|
Command::USER(u, m, r) => Message::new(None, "USER", Some(vec![u, m, "*"]), Some(r)),
|
||||||
|
@ -162,7 +163,7 @@ impl<'a> Command<'a> {
|
||||||
Command::MODE(t, m, Some(p)) => Message::new(None, "MODE", Some(vec![t, m, p]), None),
|
Command::MODE(t, m, Some(p)) => Message::new(None, "MODE", Some(vec![t, m, p]), None),
|
||||||
Command::MODE(t, m, None) => Message::new(None, "MODE", Some(vec![t, m]), None),
|
Command::MODE(t, m, None) => Message::new(None, "MODE", Some(vec![t, m]), None),
|
||||||
Command::SERVICE(n, r, d, t, re, i) => Message::new(None, "SERVICE",
|
Command::SERVICE(n, r, d, t, re, i) => Message::new(None, "SERVICE",
|
||||||
Some(vec![n, r, d, t, re]), Some(i)),
|
Some(vec![n, r, d, t, re]), Some(i)),
|
||||||
Command::QUIT(Some(m)) => Message::new(None, "QUIT", None, Some(m)),
|
Command::QUIT(Some(m)) => Message::new(None, "QUIT", None, Some(m)),
|
||||||
Command::QUIT(None) => Message::new(None, "QUIT", None, None),
|
Command::QUIT(None) => Message::new(None, "QUIT", None, None),
|
||||||
Command::SQUIT(s, c) => Message::new(None, "SQUIT", Some(vec![s]), Some(c)),
|
Command::SQUIT(s, c) => Message::new(None, "SQUIT", Some(vec![s]), Some(c)),
|
||||||
|
@ -186,7 +187,7 @@ impl<'a> Command<'a> {
|
||||||
Command::MOTD(Some(t)) => Message::new(None, "MOTD", None, Some(t)),
|
Command::MOTD(Some(t)) => Message::new(None, "MOTD", None, Some(t)),
|
||||||
Command::MOTD(None) => Message::new(None, "MOTD", None, None),
|
Command::MOTD(None) => Message::new(None, "MOTD", None, None),
|
||||||
Command::LUSERS(Some(m), Some(t)) => Message::new(None, "LUSERS", Some(vec![m]),
|
Command::LUSERS(Some(m), Some(t)) => Message::new(None, "LUSERS", Some(vec![m]),
|
||||||
Some(t)),
|
Some(t)),
|
||||||
Command::LUSERS(Some(m), None) => Message::new(None, "LUSERS", Some(vec![m]), None),
|
Command::LUSERS(Some(m), None) => Message::new(None, "LUSERS", Some(vec![m]), None),
|
||||||
Command::LUSERS(None, _) => Message::new(None, "LUSERS", None, None),
|
Command::LUSERS(None, _) => Message::new(None, "LUSERS", None, None),
|
||||||
Command::VERSION(Some(t)) => Message::new(None, "VERSION", None, Some(t)),
|
Command::VERSION(Some(t)) => Message::new(None, "VERSION", None, Some(t)),
|
||||||
|
@ -200,7 +201,7 @@ impl<'a> Command<'a> {
|
||||||
Command::TIME(Some(t)) => Message::new(None, "TIME", None, Some(t)),
|
Command::TIME(Some(t)) => Message::new(None, "TIME", None, Some(t)),
|
||||||
Command::TIME(None) => Message::new(None, "TIME", None, None),
|
Command::TIME(None) => Message::new(None, "TIME", None, None),
|
||||||
Command::CONNECT(t, p, Some(r)) => Message::new(None, "CONNECT", Some(vec![t, p]),
|
Command::CONNECT(t, p, Some(r)) => Message::new(None, "CONNECT", Some(vec![t, p]),
|
||||||
Some(r)),
|
Some(r)),
|
||||||
Command::CONNECT(t, p, None) => Message::new(None, "CONNECT", Some(vec![t, p]), None),
|
Command::CONNECT(t, p, None) => Message::new(None, "CONNECT", Some(vec![t, p]), None),
|
||||||
Command::TRACE(Some(t)) => Message::new(None, "TRACE", None, Some(t)),
|
Command::TRACE(Some(t)) => Message::new(None, "TRACE", None, Some(t)),
|
||||||
Command::TRACE(None) => Message::new(None, "TRACE", None, None),
|
Command::TRACE(None) => Message::new(None, "TRACE", None, None),
|
||||||
|
@ -209,20 +210,20 @@ impl<'a> Command<'a> {
|
||||||
Command::INFO(Some(t)) => Message::new(None, "INFO", None, Some(t)),
|
Command::INFO(Some(t)) => Message::new(None, "INFO", None, Some(t)),
|
||||||
Command::INFO(None) => Message::new(None, "INFO", None, None),
|
Command::INFO(None) => Message::new(None, "INFO", None, None),
|
||||||
Command::SERVLIST(Some(m), Some(t)) => Message::new(None, "SERVLIST", Some(vec![m]),
|
Command::SERVLIST(Some(m), Some(t)) => Message::new(None, "SERVLIST", Some(vec![m]),
|
||||||
Some(t)),
|
Some(t)),
|
||||||
Command::SERVLIST(Some(m), None) => Message::new(None, "SERVLIST", Some(vec![m]), None),
|
Command::SERVLIST(Some(m), None) => Message::new(None, "SERVLIST", Some(vec![m]), None),
|
||||||
Command::SERVLIST(None, _) => Message::new(None, "SERVLIST", None, None),
|
Command::SERVLIST(None, _) => Message::new(None, "SERVLIST", None, None),
|
||||||
Command::SQUERY(s, t) => Message::new(None, "SQUERY", Some(vec![s, t]), None),
|
Command::SQUERY(s, t) => Message::new(None, "SQUERY", Some(vec![s, t]), None),
|
||||||
Command::WHO(Some(s), Some(true)) => Message::new(None, "WHO", Some(vec![s, "o"]),
|
Command::WHO(Some(s), Some(true)) => Message::new(None, "WHO", Some(vec![s, "o"]),
|
||||||
None),
|
None),
|
||||||
Command::WHO(Some(s), _) => Message::new(None, "WHO", Some(vec![s]), None),
|
Command::WHO(Some(s), _) => Message::new(None, "WHO", Some(vec![s]), None),
|
||||||
Command::WHO(None, _) => Message::new(None, "WHO", None, None),
|
Command::WHO(None, _) => Message::new(None, "WHO", None, None),
|
||||||
Command::WHOIS(Some(t), m) => Message::new(None, "WHOIS", Some(vec![t, m]), None),
|
Command::WHOIS(Some(t), m) => Message::new(None, "WHOIS", Some(vec![t, m]), None),
|
||||||
Command::WHOIS(None, m) => Message::new(None, "WHOIS", Some(vec![m]), None),
|
Command::WHOIS(None, m) => Message::new(None, "WHOIS", Some(vec![m]), None),
|
||||||
Command::WHOWAS(n, Some(c), Some(t)) => Message::new(None, "WHOWAS", Some(vec![n, c]),
|
Command::WHOWAS(n, Some(c), Some(t)) => Message::new(None, "WHOWAS", Some(vec![n, c]),
|
||||||
Some(t)),
|
Some(t)),
|
||||||
Command::WHOWAS(n, Some(c), None) => Message::new(None, "WHOWAS", Some(vec![n, c]),
|
Command::WHOWAS(n, Some(c), None) => Message::new(None, "WHOWAS", Some(vec![n, c]),
|
||||||
None),
|
None),
|
||||||
Command::WHOWAS(n, None, _) => Message::new(None, "WHOWAS", Some(vec![n]), None),
|
Command::WHOWAS(n, None, _) => Message::new(None, "WHOWAS", Some(vec![n]), None),
|
||||||
Command::KILL(n, c) => Message::new(None, "KILL", Some(vec![n]), Some(c)),
|
Command::KILL(n, c) => Message::new(None, "KILL", Some(vec![n]), Some(c)),
|
||||||
Command::PING(s, Some(t)) => Message::new(None, "PING", Some(vec![s]), Some(t)),
|
Command::PING(s, Some(t)) => Message::new(None, "PING", Some(vec![s]), Some(t)),
|
||||||
|
@ -236,18 +237,18 @@ impl<'a> Command<'a> {
|
||||||
Command::DIE => Message::new(None, "DIE", None, None),
|
Command::DIE => Message::new(None, "DIE", None, None),
|
||||||
Command::RESTART => Message::new(None, "RESTART", None, None),
|
Command::RESTART => Message::new(None, "RESTART", None, None),
|
||||||
Command::SUMMON(u, Some(t), Some(c)) => Message::new(None, "SUMMON", Some(vec![u, t]),
|
Command::SUMMON(u, Some(t), Some(c)) => Message::new(None, "SUMMON", Some(vec![u, t]),
|
||||||
Some(c)),
|
Some(c)),
|
||||||
Command::SUMMON(u, Some(t), None) => Message::new(None, "SUMMON", Some(vec![u, t]),
|
Command::SUMMON(u, Some(t), None) => Message::new(None, "SUMMON", Some(vec![u, t]),
|
||||||
None),
|
None),
|
||||||
Command::SUMMON(u, None, _) => Message::new(None, "SUMMON", Some(vec![u]), None),
|
Command::SUMMON(u, None, _) => Message::new(None, "SUMMON", Some(vec![u]), None),
|
||||||
Command::USERS(Some(t)) => Message::new(None, "USERS", None, Some(t)),
|
Command::USERS(Some(t)) => Message::new(None, "USERS", None, Some(t)),
|
||||||
Command::USERS(None) => Message::new(None, "USERS", None, None),
|
Command::USERS(None) => Message::new(None, "USERS", None, None),
|
||||||
Command::WALLOPS(t) => Message::new(None, "WALLOPS", None, Some(t)),
|
Command::WALLOPS(t) => Message::new(None, "WALLOPS", None, Some(t)),
|
||||||
Command::USERHOST(u) => Message::new(None, "USERHOST", Some(u), None),
|
Command::USERHOST(ref u) => Message::new(None, "USERHOST", Some(u.clone()), None),
|
||||||
Command::ISON(u) => Message::new(None, "ISON", Some(u), None),
|
Command::ISON(ref u) => Message::new(None, "ISON", Some(u.clone()), None),
|
||||||
Command::SAJOIN(n, c) => Message::new(None, "SAJOIN", Some(vec![n, c]), None),
|
Command::SAJOIN(n, c) => Message::new(None, "SAJOIN", Some(vec![n, c]), None),
|
||||||
Command::SAMODE(t, m, Some(p)) => Message::new(None, "SAMODE", Some(vec![t, m, p]),
|
Command::SAMODE(t, m, Some(p)) => Message::new(None, "SAMODE", Some(vec![t, m, p]),
|
||||||
None),
|
None),
|
||||||
Command::SAMODE(t, m, None) => Message::new(None, "SAMODE", Some(vec![t, m]), None),
|
Command::SAMODE(t, m, None) => Message::new(None, "SAMODE", Some(vec![t, m]), None),
|
||||||
Command::SANICK(o, n) => Message::new(None, "SANICK", Some(vec![o, n]), None),
|
Command::SANICK(o, n) => Message::new(None, "SANICK", Some(vec![o, n]), None),
|
||||||
Command::SAPART(c, r) => Message::new(None, "SAPART", Some(vec![c]), Some(r)),
|
Command::SAPART(c, r) => Message::new(None, "SAPART", Some(vec![c]), Some(r)),
|
||||||
|
@ -262,6 +263,9 @@ impl<'a> Command<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Command<'a> {
|
||||||
/// Converts a Message into a Command.
|
/// Converts a Message into a Command.
|
||||||
#[stable]
|
#[stable]
|
||||||
pub fn from_message(m: &'a Message) -> IoResult<Command<'a>> {
|
pub fn from_message(m: &'a Message) -> IoResult<Command<'a>> {
|
||||||
|
@ -981,7 +985,7 @@ impl CapSubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for CapSubCommand {
|
impl FromStr for CapSubCommand {
|
||||||
fn from_str(s: &str) -> Option<CapSubCommand> {
|
fn from_str(s: &str) -> Option<CapSubCommand> {
|
||||||
match s {
|
match s {
|
||||||
"LS" => Some(CapSubCommand::LS),
|
"LS" => Some(CapSubCommand::LS),
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
/// Represents something that can be converted to a message.
|
||||||
|
pub trait ToMessage {
|
||||||
|
|
||||||
|
/// Convert to message.
|
||||||
|
fn to_message(&self) -> Message;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// IRC Message data.
|
/// IRC Message data.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[deriving(Clone, PartialEq, Show)]
|
#[deriving(Clone, PartialEq, Show)]
|
||||||
|
@ -54,6 +62,14 @@ impl Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToMessage for Message {
|
||||||
|
|
||||||
|
fn to_message(&self) -> Message {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for Message {
|
impl FromStr for Message {
|
||||||
fn from_str(s: &str) -> Option<Message> {
|
fn from_str(s: &str) -> Option<Message> {
|
||||||
let mut state = s.clone();
|
let mut state = s.clone();
|
||||||
|
|
|
@ -8,6 +8,7 @@ use conn::{Connection, NetStream};
|
||||||
use data::{Command, Config, Message, Response, User};
|
use data::{Command, Config, Message, Response, User};
|
||||||
use data::Command::{JOIN, NICK, NICKSERV, PONG};
|
use data::Command::{JOIN, NICK, NICKSERV, PONG};
|
||||||
use data::kinds::{IrcReader, IrcWriter};
|
use data::kinds::{IrcReader, IrcWriter};
|
||||||
|
use data::message::ToMessage;
|
||||||
#[cfg(feature = "ctcp")] use time::now;
|
#[cfg(feature = "ctcp")] use time::now;
|
||||||
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
@ -42,7 +43,7 @@ pub struct IrcServer<T: IrcReader, U: IrcWriter> {
|
||||||
pub type NetIrcServer = IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>>;
|
pub type NetIrcServer = IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>>;
|
||||||
|
|
||||||
impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
/// Creates a new IRC Server connection from the configuration at the specified path,
|
/// Creates a new IRC Server connection from the configuration at the specified path,
|
||||||
/// connecting immediately.
|
/// connecting immediately.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn new(config: &str) -> IoResult<NetIrcServer> {
|
pub fn new(config: &str) -> IoResult<NetIrcServer> {
|
||||||
|
@ -65,7 +66,7 @@ impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
/// Reconnects to the IRC server.
|
/// Reconnects to the IRC server.
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn reconnect(&self) -> IoResult<()> {
|
pub fn reconnect(&self) -> IoResult<()> {
|
||||||
self.conn.reconnect(self.config().server(), self.config.port())
|
self.conn.reconnect(self.config().server(), self.config.port())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
for chan in self.config.channels().into_iter() {
|
for chan in self.config.channels().into_iter() {
|
||||||
self.send(JOIN(chan[], None)).unwrap();
|
self.send(JOIN(chan[], None)).unwrap();
|
||||||
}
|
}
|
||||||
} else if resp == Response::ERR_NICKNAMEINUSE ||
|
} else if resp == Response::ERR_NICKNAMEINUSE ||
|
||||||
resp == Response::ERR_ERRONEOUSNICKNAME {
|
resp == Response::ERR_ERRONEOUSNICKNAME {
|
||||||
let alt_nicks = self.config.get_alternate_nicknames();
|
let alt_nicks = self.config.get_alternate_nicknames();
|
||||||
let mut index = self.alt_nick_index.write();
|
let mut index = self.alt_nick_index.write();
|
||||||
|
@ -190,7 +191,7 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
let resp = if target.starts_with("#") { target[] } else { source };
|
let resp = if target.starts_with("#") { target[] } else { source };
|
||||||
match msg.suffix {
|
match msg.suffix {
|
||||||
Some(ref msg) if msg.starts_with("\u{001}") => {
|
Some(ref msg) if msg.starts_with("\u{001}") => {
|
||||||
let tokens: Vec<_> = {
|
let tokens: Vec<_> = {
|
||||||
let end = if msg.ends_with("\u{001}") {
|
let end = if msg.ends_with("\u{001}") {
|
||||||
msg.len() - 1
|
msg.len() - 1
|
||||||
} else {
|
} else {
|
||||||
|
@ -199,9 +200,9 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
msg[1..end].split_str(" ").collect()
|
msg[1..end].split_str(" ").collect()
|
||||||
};
|
};
|
||||||
println!("we made it this far.");
|
println!("we made it this far.");
|
||||||
match tokens[0] {
|
match tokens[0] {
|
||||||
"FINGER" => self.send_ctcp(resp, format!("FINGER :{} ({})",
|
"FINGER" => self.send_ctcp(resp, format!("FINGER :{} ({})",
|
||||||
self.config.real_name(),
|
self.config.real_name(),
|
||||||
self.config.username())[]),
|
self.config.username())[]),
|
||||||
"VERSION" => self.send_ctcp(resp, "VERSION irc:git:Rust"),
|
"VERSION" => self.send_ctcp(resp, "VERSION irc:git:Rust"),
|
||||||
"SOURCE" => {
|
"SOURCE" => {
|
||||||
|
@ -212,7 +213,7 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
},
|
},
|
||||||
"PING" => self.send_ctcp(resp, format!("PING {}", tokens[1])[]),
|
"PING" => self.send_ctcp(resp, format!("PING {}", tokens[1])[]),
|
||||||
"TIME" => self.send_ctcp(resp, format!("TIME :{}", now().rfc822z())[]),
|
"TIME" => self.send_ctcp(resp, format!("TIME :{}", now().rfc822z())[]),
|
||||||
"USERINFO" => self.send_ctcp(resp, format!("USERINFO :{}",
|
"USERINFO" => self.send_ctcp(resp, format!("USERINFO :{}",
|
||||||
self.config.user_info())[]),
|
self.config.user_info())[]),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +277,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Iterator<IoResult<Message>> for ServerItera
|
||||||
desc: "Failed to parse message.",
|
desc: "Failed to parse message.",
|
||||||
detail: Some(msg)
|
detail: Some(msg)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
match res {
|
match res {
|
||||||
Err(ref err) if err.kind == IoErrorKind::EndOfFile => None,
|
Err(ref err) if err.kind == IoErrorKind::EndOfFile => None,
|
||||||
|
@ -451,7 +452,7 @@ mod test {
|
||||||
// but ignores the ordering of these entries.
|
// but ignores the ordering of these entries.
|
||||||
let mut levels = server.list_users("#test").unwrap()[0].access_levels();
|
let mut levels = server.list_users("#test").unwrap()[0].access_levels();
|
||||||
levels.retain(|l| exp.access_levels().contains(l));
|
levels.retain(|l| exp.access_levels().contains(l));
|
||||||
assert_eq!(levels.len(), exp.access_levels().len());
|
assert_eq!(levels.len(), exp.access_levels().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -492,7 +493,7 @@ mod test {
|
||||||
for message in server.iter() {
|
for message in server.iter() {
|
||||||
println!("{}", message);
|
println!("{}", message);
|
||||||
}
|
}
|
||||||
assert_eq!(get_server_value(server)[],
|
assert_eq!(get_server_value(server)[],
|
||||||
"NOTICE test :\u{001}SOURCE https://github.com/aatxe/irc\u{001}\r\n\
|
"NOTICE test :\u{001}SOURCE https://github.com/aatxe/irc\u{001}\r\n\
|
||||||
NOTICE test :\u{001}SOURCE\u{001}\r\n");
|
NOTICE test :\u{001}SOURCE\u{001}\r\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue