Updated to 0.7.9 and re-evaluated library stabilization.
This commit is contained in:
parent
d0b54f8119
commit
768c6f556f
10 changed files with 128 additions and 129 deletions
10
Cargo.toml
10
Cargo.toml
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
|
|
||||||
name = "irc"
|
name = "irc"
|
||||||
version = "0.7.8"
|
version = "0.7.9"
|
||||||
description = "A simple, thread-safe IRC client library."
|
description = "A simple, thread-safe IRC client library."
|
||||||
authors = ["Aaron Weiss <aaronweiss74@gmail.com>"]
|
authors = ["Aaron Weiss <aaronweiss74@gmail.com>"]
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
|
@ -18,19 +18,19 @@ encode = ["encoding"]
|
||||||
ssl = ["openssl"]
|
ssl = ["openssl"]
|
||||||
|
|
||||||
[dependencies.rustc-serialize]
|
[dependencies.rustc-serialize]
|
||||||
rustc-serialize = "~0.2.5"
|
rustc-serialize = "~0.2.7"
|
||||||
|
|
||||||
[dependencies.time]
|
[dependencies.time]
|
||||||
|
|
||||||
time = "~0.1.10"
|
time = "~0.1.12"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.encoding]
|
[dependencies.encoding]
|
||||||
|
|
||||||
encoding = "~0.2.16"
|
encoding = "~0.2.18"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.openssl]
|
[dependencies.openssl]
|
||||||
|
|
||||||
openssl = "~0.2.13"
|
openssl = "~0.2.15"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
29
src/conn.rs
29
src/conn.rs
|
@ -1,5 +1,5 @@
|
||||||
//! Thread-safe connections on IrcStreams.
|
//! Thread-safe connections on IrcStreams.
|
||||||
#![experimental]
|
#![stable]
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io::{BufferedReader, BufferedWriter, IoResult, TcpStream};
|
use std::io::{BufferedReader, BufferedWriter, IoResult, TcpStream};
|
||||||
#[cfg(any(feature = "encode", feature = "ssl"))] use std::io::{IoError, IoErrorKind};
|
#[cfg(any(feature = "encode", feature = "ssl"))] use std::io::{IoError, IoErrorKind};
|
||||||
|
@ -12,7 +12,7 @@ use data::message::ToMessage;
|
||||||
#[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]
|
#[stable]
|
||||||
pub struct Connection<T: IrcReader, U: IrcWriter> {
|
pub struct Connection<T: IrcReader, U: IrcWriter> {
|
||||||
reader: Mutex<T>,
|
reader: Mutex<T>,
|
||||||
writer: Mutex<U>,
|
writer: Mutex<U>,
|
||||||
|
@ -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]
|
#[stable]
|
||||||
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))
|
||||||
|
@ -41,7 +41,7 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
|
|
||||||
/// 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]
|
#[stable]
|
||||||
pub fn connect_ssl(host: &str, port: u16) -> IoResult<NetConnection> {
|
pub fn connect_ssl(host: &str, port: u16) -> IoResult<NetConnection> {
|
||||||
let (reader, writer) = try!(Connection::connect_ssl_internal(host, port));
|
let (reader, writer) = try!(Connection::connect_ssl_internal(host, port));
|
||||||
Ok(Connection::new(reader, writer))
|
Ok(Connection::new(reader, writer))
|
||||||
|
@ -64,6 +64,7 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reconnects to the specified server, dropping the current connection.
|
/// Reconnects to the specified server, dropping the current connection.
|
||||||
|
#[unstable = "Feature is relatively new."]
|
||||||
pub fn reconnect(&self, host: &str, port: u16) -> IoResult<()> {
|
pub fn reconnect(&self, host: &str, port: u16) -> IoResult<()> {
|
||||||
let use_ssl = match self.reader.lock().unwrap().get_ref() {
|
let use_ssl = match self.reader.lock().unwrap().get_ref() {
|
||||||
&NetStream::UnsecuredTcpStream(_) => false,
|
&NetStream::UnsecuredTcpStream(_) => false,
|
||||||
|
@ -81,13 +82,13 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the keepalive for the network stream.
|
/// Sets the keepalive for the network stream.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
pub fn set_keepalive(&self, delay_in_seconds: Option<usize>) -> IoResult<()> {
|
pub fn set_keepalive(&self, delay_in_seconds: Option<usize>) -> 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]
|
#[unstable = "Feature is relatively new."]
|
||||||
pub fn set_timeout(&self, timeout_ms: Option<u64>) {
|
pub fn set_timeout(&self, timeout_ms: Option<u64>) {
|
||||||
self.mod_stream(|tcp| Ok(tcp.set_timeout(timeout_ms))).unwrap(); // this cannot fail.
|
self.mod_stream(|tcp| Ok(tcp.set_timeout(timeout_ms))).unwrap(); // this cannot fail.
|
||||||
}
|
}
|
||||||
|
@ -104,7 +105,7 @@ impl Connection<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
|
|
||||||
impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
/// Creates a new connection from an IrcReader and an IrcWriter.
|
/// Creates a new connection from an IrcReader and an IrcWriter.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn new(reader: T, writer: U) -> Connection<T, U> {
|
pub fn new(reader: T, writer: U) -> Connection<T, U> {
|
||||||
Connection {
|
Connection {
|
||||||
reader: Mutex::new(reader),
|
reader: Mutex::new(reader),
|
||||||
|
@ -113,7 +114,7 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a Message over this connection.
|
/// Sends a Message over this connection.
|
||||||
#[experimental]
|
#[experimental = "Design is very new."]
|
||||||
#[cfg(feature = "encode")]
|
#[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) -> IoResult<()> {
|
||||||
let encoding = match encoding_from_whatwg_label(encoding) {
|
let encoding = match encoding_from_whatwg_label(encoding) {
|
||||||
|
@ -139,7 +140,7 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a message over this connection.
|
/// Sends a message over this connection.
|
||||||
#[experimental]
|
#[experimental = "Design is very new."]
|
||||||
#[cfg(not(feature = "encode"))]
|
#[cfg(not(feature = "encode"))]
|
||||||
pub fn send<T: ToMessage>(&self, to_msg: T) -> IoResult<()> {
|
pub fn send<T: ToMessage>(&self, to_msg: T) -> IoResult<()> {
|
||||||
let mut writer = self.writer.lock().unwrap();
|
let mut writer = self.writer.lock().unwrap();
|
||||||
|
@ -148,7 +149,7 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives a single line from this connection.
|
/// Receives a single line from this connection.
|
||||||
#[experimental]
|
#[stable]
|
||||||
#[cfg(feature = "encoding")]
|
#[cfg(feature = "encoding")]
|
||||||
pub fn recv(&self, encoding: &str) -> IoResult<String> {
|
pub fn recv(&self, encoding: &str) -> IoResult<String> {
|
||||||
let encoding = match encoding_from_whatwg_label(encoding) {
|
let encoding = match encoding_from_whatwg_label(encoding) {
|
||||||
|
@ -172,20 +173,20 @@ impl<T: IrcReader, U: IrcWriter> Connection<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives a single line from this connection.
|
/// Receives a single line from this connection.
|
||||||
#[experimental]
|
#[stable]
|
||||||
#[cfg(not(feature = "encoding"))]
|
#[cfg(not(feature = "encoding"))]
|
||||||
pub fn recv(&self) -> IoResult<String> {
|
pub fn recv(&self) -> IoResult<String> {
|
||||||
self.reader.lock().unwrap().read_line()
|
self.reader.lock().unwrap().read_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquires the Reader lock.
|
/// Acquires the Reader lock.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn reader<'a>(&'a self) -> MutexGuard<'a, T> {
|
pub fn reader<'a>(&'a self) -> MutexGuard<'a, T> {
|
||||||
self.reader.lock().unwrap()
|
self.reader.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquires the Writer lock.
|
/// Acquires the Writer lock.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn writer<'a>(&'a self) -> MutexGuard<'a, U> {
|
pub fn writer<'a>(&'a self) -> MutexGuard<'a, U> {
|
||||||
self.writer.lock().unwrap()
|
self.writer.lock().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ fn ssl_to_io<T>(res: Result<T, SslError>) -> IoResult<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An abstraction over different networked streams.
|
/// An abstraction over different networked streams.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub enum NetStream {
|
pub enum NetStream {
|
||||||
/// An unsecured TcpStream.
|
/// An unsecured TcpStream.
|
||||||
UnsecuredTcpStream(TcpStream),
|
UnsecuredTcpStream(TcpStream),
|
||||||
|
|
|
@ -12,72 +12,72 @@ use data::message::{Message, ToMessage};
|
||||||
#[derive(Show, PartialEq)]
|
#[derive(Show, PartialEq)]
|
||||||
pub enum Command<'a> {
|
pub enum Command<'a> {
|
||||||
// 3.1 Connection Registration
|
// 3.1 Connection Registration
|
||||||
/// PASS password
|
/// PASS :password
|
||||||
PASS(&'a str),
|
PASS(&'a str),
|
||||||
/// NICK nickname
|
/// NICK :nickname
|
||||||
NICK(&'a str),
|
NICK(&'a str),
|
||||||
/// USER user mode * realname
|
/// USER user mode * :realname
|
||||||
USER(&'a str, &'a str, &'a str),
|
USER(&'a str, &'a str, &'a str),
|
||||||
/// OPER name password
|
/// OPER name :password
|
||||||
OPER(&'a str, &'a str),
|
OPER(&'a str, &'a str),
|
||||||
/// MODE nickname modes
|
/// MODE nickname modes
|
||||||
/// MODE channel modes [modeparams]
|
/// MODE channel modes [modeparams]
|
||||||
MODE(&'a str, &'a str, Option<&'a str>),
|
MODE(&'a str, &'a str, Option<&'a str>),
|
||||||
/// SERVICE nickname reserved distribution type reserved info
|
/// SERVICE nickname reserved distribution type reserved :info
|
||||||
SERVICE(&'a str, &'a str, &'a str, &'a str, &'a str, &'a str),
|
SERVICE(&'a str, &'a str, &'a str, &'a str, &'a str, &'a str),
|
||||||
/// QUIT Quit Message
|
/// QUIT :comment
|
||||||
QUIT(Option<&'a str>),
|
QUIT(Option<&'a str>),
|
||||||
/// SQUIT server comment
|
/// SQUIT server :comment
|
||||||
SQUIT(&'a str, &'a str),
|
SQUIT(&'a str, &'a str),
|
||||||
|
|
||||||
// 3.2 Channel operations
|
// 3.2 Channel operations
|
||||||
/// JOIN chanlist [chankeys]
|
/// JOIN chanlist [chankeys]
|
||||||
JOIN(&'a str, Option<&'a str>),
|
JOIN(&'a str, Option<&'a str>),
|
||||||
/// PART chanlist [Part Message]
|
/// PART chanlist :[comment]
|
||||||
PART(&'a str, Option<&'a str>),
|
PART(&'a str, Option<&'a str>),
|
||||||
// MODE is already defined.
|
// MODE is already defined.
|
||||||
// MODE(&'a str, &'a str, Option<&'a str>),
|
// MODE(&'a str, &'a str, Option<&'a str>),
|
||||||
/// TOPIC channel [topic]
|
/// TOPIC channel :[topic]
|
||||||
TOPIC(&'a str, Option<&'a str>),
|
TOPIC(&'a str, Option<&'a str>),
|
||||||
/// NAMES [chanlist [target]]
|
/// NAMES [chanlist :[target]]
|
||||||
NAMES(Option<&'a str>, Option<&'a str>),
|
NAMES(Option<&'a str>, Option<&'a str>),
|
||||||
/// LIST [chanlist [target]]
|
/// LIST [chanlist :[target]]
|
||||||
LIST(Option<&'a str>, Option<&'a str>),
|
LIST(Option<&'a str>, Option<&'a str>),
|
||||||
/// INVITE nickname channel
|
/// INVITE nickname channel
|
||||||
INVITE(&'a str, &'a str),
|
INVITE(&'a str, &'a str),
|
||||||
/// KICK chanlist userlist [comment]
|
/// KICK chanlist userlist :[comment]
|
||||||
KICK(&'a str, &'a str, Option<&'a str>),
|
KICK(&'a str, &'a str, Option<&'a str>),
|
||||||
|
|
||||||
// 3.3 Sending messages
|
// 3.3 Sending messages
|
||||||
/// PRIVMSG msgtarget text to be sent
|
/// PRIVMSG msgtarget :message
|
||||||
PRIVMSG(&'a str, &'a str),
|
PRIVMSG(&'a str, &'a str),
|
||||||
/// NOTICE msgtarget text
|
/// NOTICE msgtarget :message
|
||||||
NOTICE(&'a str, &'a str),
|
NOTICE(&'a str, &'a str),
|
||||||
|
|
||||||
// 3.4 Server queries and commands
|
// 3.4 Server queries and commands
|
||||||
/// MOTD [target]
|
/// MOTD :[target]
|
||||||
MOTD(Option<&'a str>),
|
MOTD(Option<&'a str>),
|
||||||
/// LUSERS [mask [target]]
|
/// LUSERS [mask :[target]]
|
||||||
LUSERS(Option<&'a str>, Option<&'a str>),
|
LUSERS(Option<&'a str>, Option<&'a str>),
|
||||||
/// VERSION [target]
|
/// VERSION :[target]
|
||||||
VERSION(Option<&'a str>),
|
VERSION(Option<&'a str>),
|
||||||
/// STATS [query [target]]
|
/// STATS [query :[target]]
|
||||||
STATS(Option<&'a str>, Option<&'a str>),
|
STATS(Option<&'a str>, Option<&'a str>),
|
||||||
/// LINKS [[remote server] server mask]
|
/// LINKS [[remote server] server :mask]
|
||||||
LINKS(Option<&'a str>, Option<&'a str>),
|
LINKS(Option<&'a str>, Option<&'a str>),
|
||||||
/// TIME [target]
|
/// TIME :[target]
|
||||||
TIME(Option<&'a str>),
|
TIME(Option<&'a str>),
|
||||||
/// CONNECT target server port [remote server]
|
/// CONNECT target server port :[remote server]
|
||||||
CONNECT(&'a str, &'a str, Option<&'a str>),
|
CONNECT(&'a str, &'a str, Option<&'a str>),
|
||||||
/// TRACE [target]
|
/// TRACE :[target]
|
||||||
TRACE(Option<&'a str>),
|
TRACE(Option<&'a str>),
|
||||||
/// ADMIN [target]
|
/// ADMIN :[target]
|
||||||
ADMIN(Option<&'a str>),
|
ADMIN(Option<&'a str>),
|
||||||
/// INFO [target]
|
/// INFO :[target]
|
||||||
INFO(Option<&'a str>),
|
INFO(Option<&'a str>),
|
||||||
|
|
||||||
// 3.5 Service Query and Commands
|
// 3.5 Service Query and Commands
|
||||||
/// SERVLIST [mask [type]]
|
/// SERVLIST [mask :[type]]
|
||||||
SERVLIST(Option<&'a str>, Option<&'a str>),
|
SERVLIST(Option<&'a str>, Option<&'a str>),
|
||||||
/// SQUERY servicename text
|
/// SQUERY servicename text
|
||||||
SQUERY(&'a str, &'a str),
|
SQUERY(&'a str, &'a str),
|
||||||
|
@ -87,22 +87,22 @@ pub enum Command<'a> {
|
||||||
WHO(Option<&'a str>, Option<bool>),
|
WHO(Option<&'a str>, Option<bool>),
|
||||||
/// WHOIS [target] masklist
|
/// WHOIS [target] masklist
|
||||||
WHOIS(Option<&'a str>, &'a str),
|
WHOIS(Option<&'a str>, &'a str),
|
||||||
/// WHOWAS nicklist [count [target]]
|
/// WHOWAS nicklist [count :[target]]
|
||||||
WHOWAS(&'a str, Option<&'a str>, Option<&'a str>),
|
WHOWAS(&'a str, Option<&'a str>, Option<&'a str>),
|
||||||
|
|
||||||
// 3.7 Miscellaneous messages
|
// 3.7 Miscellaneous messages
|
||||||
/// KILL nickname comment
|
/// KILL nickname :comment
|
||||||
KILL(&'a str, &'a str),
|
KILL(&'a str, &'a str),
|
||||||
/// PING server1 [server2]
|
/// PING server1 :[server2]
|
||||||
PING(&'a str, Option<&'a str>),
|
PING(&'a str, Option<&'a str>),
|
||||||
/// PONG server [server2]
|
/// PONG server :[server2]
|
||||||
PONG(&'a str, Option<&'a str>),
|
PONG(&'a str, Option<&'a str>),
|
||||||
/// ERROR error message
|
/// ERROR :message
|
||||||
ERROR(&'a str),
|
ERROR(&'a str),
|
||||||
|
|
||||||
|
|
||||||
// 4 Optional Features
|
// 4 Optional Features
|
||||||
/// AWAY [text]
|
/// AWAY :[message]
|
||||||
AWAY(Option<&'a str>),
|
AWAY(Option<&'a str>),
|
||||||
/// REHASH
|
/// REHASH
|
||||||
REHASH,
|
REHASH,
|
||||||
|
@ -110,11 +110,11 @@ pub enum Command<'a> {
|
||||||
DIE,
|
DIE,
|
||||||
/// RESTART
|
/// RESTART
|
||||||
RESTART,
|
RESTART,
|
||||||
/// SUMMON user [target [channel]]
|
/// SUMMON user [target :[channel]]
|
||||||
SUMMON(&'a str, Option<&'a str>, Option<&'a str>),
|
SUMMON(&'a str, Option<&'a str>, Option<&'a str>),
|
||||||
/// USERS [target]
|
/// USERS :[target]
|
||||||
USERS(Option<&'a str>),
|
USERS(Option<&'a str>),
|
||||||
/// WALLOPS Text to be sent
|
/// WALLOPS :Text to be sent
|
||||||
WALLOPS(&'a str),
|
WALLOPS(&'a str),
|
||||||
/// USERHOST space-separated nicklist
|
/// USERHOST space-separated nicklist
|
||||||
USERHOST(Vec<&'a str>),
|
USERHOST(Vec<&'a str>),
|
||||||
|
@ -128,9 +128,9 @@ pub enum Command<'a> {
|
||||||
SAMODE(&'a str, &'a str, Option<&'a str>),
|
SAMODE(&'a str, &'a str, Option<&'a str>),
|
||||||
/// SANICK old nickname new nickname
|
/// SANICK old nickname new nickname
|
||||||
SANICK(&'a str, &'a str),
|
SANICK(&'a str, &'a str),
|
||||||
/// SAPART nickname reason
|
/// SAPART nickname :comment
|
||||||
SAPART(&'a str, &'a str),
|
SAPART(&'a str, &'a str),
|
||||||
/// SAQUIT nickname reason
|
/// SAQUIT nickname :comment
|
||||||
SAQUIT(&'a str, &'a str),
|
SAQUIT(&'a str, &'a str),
|
||||||
/// NICKSERV message
|
/// NICKSERV message
|
||||||
NICKSERV(&'a str),
|
NICKSERV(&'a str),
|
||||||
|
@ -146,7 +146,8 @@ pub enum Command<'a> {
|
||||||
MEMOSERV(&'a str),
|
MEMOSERV(&'a str),
|
||||||
|
|
||||||
// Capabilities extension to IRCv3
|
// Capabilities extension to IRCv3
|
||||||
/// CAP COMMAND [param]
|
/// CAP COMMAND :[param]
|
||||||
|
#[experimental = "This command is not entirely specification compliant."]
|
||||||
CAP(CapSubCommand, Option<&'a str>),
|
CAP(CapSubCommand, Option<&'a str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_serialize::json::decode;
|
||||||
|
|
||||||
/// Configuration data.
|
/// Configuration data.
|
||||||
#[derive(Clone, RustcDecodable, Default, PartialEq, Show)]
|
#[derive(Clone, RustcDecodable, Default, PartialEq, Show)]
|
||||||
#[unstable]
|
#[stable]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// A list of the owners of the bot by nickname.
|
/// A list of the owners of the bot by nickname.
|
||||||
pub owners: Option<Vec<String>>,
|
pub owners: Option<Vec<String>>,
|
||||||
|
@ -70,21 +70,21 @@ impl Config {
|
||||||
|
|
||||||
/// Gets the nickname specified in the configuration.
|
/// Gets the nickname specified in the configuration.
|
||||||
/// This will panic if not specified.
|
/// This will panic if not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn nickname(&self) -> &str {
|
pub fn nickname(&self) -> &str {
|
||||||
self.nickname.as_ref().map(|s| &s[]).unwrap()
|
self.nickname.as_ref().map(|s| &s[]).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the bot's nickserv password specified in the configuration.
|
/// Gets the bot's nickserv password specified in the configuration.
|
||||||
/// This defaults to an empty string when not specified.
|
/// This defaults to an empty string when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn nick_password(&self) -> &str {
|
pub fn nick_password(&self) -> &str {
|
||||||
self.nick_password.as_ref().map(|s| &s[]).unwrap_or("")
|
self.nick_password.as_ref().map(|s| &s[]).unwrap_or("")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the alternate nicknames specified in the configuration.
|
/// Gets the alternate nicknames specified in the configuration.
|
||||||
/// This defaults to an empty vector when not specified.
|
/// This defaults to an empty vector when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn get_alternate_nicknames(&self) -> Vec<&str> {
|
pub fn get_alternate_nicknames(&self) -> Vec<&str> {
|
||||||
self.alt_nicks.as_ref().map(|v| v.iter().map(|s| &s[]).collect()).unwrap_or(vec![])
|
self.alt_nicks.as_ref().map(|v| v.iter().map(|s| &s[]).collect()).unwrap_or(vec![])
|
||||||
}
|
}
|
||||||
|
@ -92,28 +92,28 @@ impl Config {
|
||||||
|
|
||||||
/// Gets the username specified in the configuration.
|
/// Gets the username specified in the configuration.
|
||||||
/// This defaults to the user's nickname when not specified.
|
/// This defaults to the user's nickname when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn username(&self) -> &str {
|
pub fn username(&self) -> &str {
|
||||||
self.username.as_ref().map(|s| &s[]).unwrap_or(self.nickname())
|
self.username.as_ref().map(|s| &s[]).unwrap_or(self.nickname())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the real name specified in the configuration.
|
/// Gets the real name specified in the configuration.
|
||||||
/// This defaults to the user's nickname when not specified.
|
/// This defaults to the user's nickname when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn real_name(&self) -> &str {
|
pub fn real_name(&self) -> &str {
|
||||||
self.realname.as_ref().map(|s| &s[]).unwrap_or(self.nickname())
|
self.realname.as_ref().map(|s| &s[]).unwrap_or(self.nickname())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the address of the server specified in the configuration.
|
/// Gets the address of the server specified in the configuration.
|
||||||
/// This panics when not specified.
|
/// This panics when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn server(&self) -> &str {
|
pub fn server(&self) -> &str {
|
||||||
self.server.as_ref().map(|s| &s[]).unwrap()
|
self.server.as_ref().map(|s| &s[]).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the port of the server specified in the configuration.
|
/// Gets the port of the server specified in the configuration.
|
||||||
/// This defaults to 6667 (or 6697 if use_ssl is specified as true) when not specified.
|
/// This defaults to 6667 (or 6697 if use_ssl is specified as true) when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn port(&self) -> u16 {
|
pub fn port(&self) -> u16 {
|
||||||
self.port.as_ref().map(|p| *p).unwrap_or(if self.use_ssl() {
|
self.port.as_ref().map(|p| *p).unwrap_or(if self.use_ssl() {
|
||||||
6697
|
6697
|
||||||
|
@ -124,35 +124,35 @@ impl Config {
|
||||||
|
|
||||||
/// Gets the server password specified in the configuration.
|
/// Gets the server password specified in the configuration.
|
||||||
/// This defaults to a blank string when not specified.
|
/// This defaults to a blank string when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn password(&self) -> &str {
|
pub fn password(&self) -> &str {
|
||||||
self.password.as_ref().map(|s| &s[]).unwrap_or("")
|
self.password.as_ref().map(|s| &s[]).unwrap_or("")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets whether or not to use SSL with this connection.
|
/// Gets whether or not to use SSL with this connection.
|
||||||
/// This defaults to false when not specified.
|
/// This defaults to false when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn use_ssl(&self) -> bool {
|
pub fn use_ssl(&self) -> bool {
|
||||||
self.use_ssl.as_ref().map(|u| *u).unwrap_or(false)
|
self.use_ssl.as_ref().map(|u| *u).unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the encoding to use for this connection. This requires the encode feature to work.
|
/// Gets the encoding to use for this connection. This requires the encode feature to work.
|
||||||
/// This defaults to UTF-8 when not specified.
|
/// This defaults to UTF-8 when not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn encoding(&self) -> &str {
|
pub fn encoding(&self) -> &str {
|
||||||
self.encoding.as_ref().map(|s| &s[]).unwrap_or("UTF-8")
|
self.encoding.as_ref().map(|s| &s[]).unwrap_or("UTF-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the channels to join upon connection.
|
/// Gets the channels to join upon connection.
|
||||||
/// This defaults to an empty vector if it's not specified.
|
/// This defaults to an empty vector if it's not specified.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn channels(&self) -> Vec<&str> {
|
pub fn channels(&self) -> Vec<&str> {
|
||||||
self.channels.as_ref().map(|v| v.iter().map(|s| &s[]).collect()).unwrap_or(vec![])
|
self.channels.as_ref().map(|v| v.iter().map(|s| &s[]).collect()).unwrap_or(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the string to be sent in response to CTCP USERINFO requests.
|
/// Gets the string to be sent in response to CTCP USERINFO requests.
|
||||||
/// This defaults to an empty string when not specified.
|
/// This defaults to an empty string when not specified.
|
||||||
#[experimental]
|
#[unstable = "Feature is still relatively new."]
|
||||||
pub fn user_info(&self) -> &str {
|
pub fn user_info(&self) -> &str {
|
||||||
self.user_info.as_ref().map(|s| &s[]).unwrap_or("")
|
self.user_info.as_ref().map(|s| &s[]).unwrap_or("")
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ impl Config {
|
||||||
/// Looks up the specified string in the options map.
|
/// Looks up the specified string in the options map.
|
||||||
/// This uses indexing, and thus panics when the string is not present.
|
/// This uses indexing, and thus panics when the string is not present.
|
||||||
/// This will also panic if used and there are no options.
|
/// This will also panic if used and there are no options.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn get_option(&self, option: &str) -> &str {
|
pub fn get_option(&self, option: &str) -> &str {
|
||||||
self.options.as_ref().map(|o| &o[option.to_owned()][]).unwrap()
|
self.options.as_ref().map(|o| &o[option.to_owned()][]).unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::ToOwned;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
/// IRC Message data.
|
/// IRC Message data.
|
||||||
#[experimental]
|
#[stable]
|
||||||
#[derive(Clone, PartialEq, Show)]
|
#[derive(Clone, PartialEq, Show)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
/// The message prefix (or source) as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
|
/// The message prefix (or source) as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
|
||||||
|
@ -20,7 +20,7 @@ pub struct Message {
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
/// Creates a new Message.
|
/// Creates a new Message.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn new(prefix: Option<&str>, command: &str, args: Option<Vec<&str>>, suffix: Option<&str>)
|
pub fn new(prefix: Option<&str>, command: &str, args: Option<Vec<&str>>, suffix: Option<&str>)
|
||||||
-> Message {
|
-> Message {
|
||||||
Message {
|
Message {
|
||||||
|
@ -32,13 +32,13 @@ impl Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the nickname of the message source, if it exists.
|
/// Gets the nickname of the message source, if it exists.
|
||||||
#[experimental]
|
#[experimental = "Feature is new."]
|
||||||
pub fn get_source_nickname(&self) -> Option<&str> {
|
pub fn get_source_nickname(&self) -> Option<&str> {
|
||||||
self.prefix.as_ref().and_then(|s| s.find('!').map(|i| &s[..i]))
|
self.prefix.as_ref().and_then(|s| s.find('!').map(|i| &s[..i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a Message into a String according to the IRC protocol.
|
/// Converts a Message into a String according to the IRC protocol.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn into_string(&self) -> String {
|
pub fn into_string(&self) -> String {
|
||||||
let mut ret = String::new();
|
let mut ret = String::new();
|
||||||
if let Some(ref prefix) = self.prefix {
|
if let Some(ref prefix) = self.prefix {
|
||||||
|
@ -98,6 +98,7 @@ impl FromStr for Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait representing the ability to be converted into a Message.
|
/// A trait representing the ability to be converted into a Message.
|
||||||
|
#[experimental = "Design is new."]
|
||||||
pub trait ToMessage {
|
pub trait ToMessage {
|
||||||
/// Converts this to a Message.
|
/// Converts this to a Message.
|
||||||
fn to_message(&self) -> Message;
|
fn to_message(&self) -> Message;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Data related to IRC functionality.
|
//! Data related to IRC functionality.
|
||||||
#![unstable]
|
#![stable]
|
||||||
|
|
||||||
pub use data::command::Command;
|
pub use data::command::Command;
|
||||||
pub use data::config::Config;
|
pub use data::config::Config;
|
||||||
|
@ -9,18 +9,18 @@ pub use data::user::{AccessLevel, User};
|
||||||
|
|
||||||
pub mod kinds {
|
pub mod kinds {
|
||||||
//! Trait definitions of appropriate Writers and Buffers for use with this library.
|
//! Trait definitions of appropriate Writers and Buffers for use with this library.
|
||||||
#![unstable]
|
#![stable]
|
||||||
|
|
||||||
/// Trait describing all possible Writers for this library.
|
/// Trait describing all possible Writers for this library.
|
||||||
#[unstable]
|
#[stable]
|
||||||
pub trait IrcWriter: Writer + Sized + Send + 'static {}
|
pub trait IrcWriter: Writer + Sized + Send + 'static {}
|
||||||
impl<T> IrcWriter for T where T: Writer + Sized + Send + 'static {}
|
impl<T> IrcWriter for T where T: Writer + Sized + Send + 'static {}
|
||||||
/// Trait describing all possible Readers for this library.
|
/// Trait describing all possible Readers for this library.
|
||||||
#[unstable]
|
#[stable]
|
||||||
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.
|
/// Trait describing all possible Streams for this library.
|
||||||
#[unstable]
|
#[unstable = "May be removed."]
|
||||||
pub trait IrcStream: IrcWriter + IrcReader {}
|
pub trait IrcStream: IrcWriter + IrcReader {}
|
||||||
impl<T> IrcStream for T where T: IrcWriter + IrcReader {}
|
impl<T> IrcStream for T where T: IrcWriter + IrcReader {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Enumeration of all the possible server responses.
|
//! Enumeration of all the possible server responses.
|
||||||
#![unstable]
|
#![stable]
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
use std::num::FromPrimitive;
|
use std::num::FromPrimitive;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -9,7 +9,7 @@ use data::message::Message;
|
||||||
/// All commands are documented with their expected form from the RFC.
|
/// All commands are documented with their expected form from the RFC.
|
||||||
#[derive(Copy, Show, PartialEq, FromPrimitive)]
|
#[derive(Copy, Show, PartialEq, FromPrimitive)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
#[unstable]
|
#[stable]
|
||||||
pub enum Response {
|
pub enum Response {
|
||||||
// Expected replies
|
// Expected replies
|
||||||
/// 001 Welcome to the Internet Relay Network <nick>!<user>@<host>
|
/// 001 Welcome to the Internet Relay Network <nick>!<user>@<host>
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::cmp::Ordering::{Less, Equal, Greater};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
/// IRC User data.
|
/// IRC User data.
|
||||||
#[unstable]
|
#[stable]
|
||||||
#[derive(Clone, Show)]
|
#[derive(Clone, Show)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
/// The user's nickname.
|
/// The user's nickname.
|
||||||
|
@ -48,19 +48,19 @@ impl User {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the user's highest access level.
|
/// Gets the user's highest access level.
|
||||||
#[experimental]
|
#[unstable = "API may change."]
|
||||||
pub fn highest_access_level(&self) -> AccessLevel {
|
pub fn highest_access_level(&self) -> AccessLevel {
|
||||||
self.highest_access_level
|
self.highest_access_level
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets all the user's access levels.
|
/// Gets all the user's access levels.
|
||||||
#[experimental]
|
#[unstable = "API may change."]
|
||||||
pub fn access_levels(&self) -> Vec<AccessLevel> {
|
pub fn access_levels(&self) -> Vec<AccessLevel> {
|
||||||
self.access_levels.clone()
|
self.access_levels.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the user's access level.
|
/// Updates the user's access level.
|
||||||
#[unstable]
|
#[unstable = "API may change."]
|
||||||
pub fn update_access_level(&mut self, mode: &str) {
|
pub fn update_access_level(&mut self, mode: &str) {
|
||||||
match mode {
|
match mode {
|
||||||
"+q" => self.add_access_level(AccessLevel::Owner),
|
"+q" => self.add_access_level(AccessLevel::Owner),
|
||||||
|
@ -77,6 +77,7 @@ impl User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds an access level to the list, and updates the highest level if necessary.
|
||||||
fn add_access_level(&mut self, level: AccessLevel) {
|
fn add_access_level(&mut self, level: AccessLevel) {
|
||||||
if level > self.highest_access_level() {
|
if level > self.highest_access_level() {
|
||||||
self.highest_access_level = level
|
self.highest_access_level = level
|
||||||
|
@ -84,6 +85,7 @@ impl User {
|
||||||
self.access_levels.push(level.clone())
|
self.access_levels.push(level.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes an access level from the list, and updates the highest level if necessary.
|
||||||
fn sub_access_level(&mut self, level: AccessLevel) {
|
fn sub_access_level(&mut self, level: AccessLevel) {
|
||||||
if let Some(n) = self.access_levels[].position_elem(&level) {
|
if let Some(n) = self.access_levels[].position_elem(&level) {
|
||||||
self.access_levels.swap_remove(n);
|
self.access_levels.swap_remove(n);
|
||||||
|
@ -179,6 +181,7 @@ impl FromStr for AccessLevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator used to parse access levels from strings.
|
||||||
struct AccessLevelIterator<'a> {
|
struct AccessLevelIterator<'a> {
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Interface for working with IRC Servers
|
//! Interface for working with IRC Servers
|
||||||
#![experimental]
|
#![stable]
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{BufferedReader, BufferedWriter, IoError, IoErrorKind, IoResult};
|
use std::io::{BufferedReader, BufferedWriter, IoError, IoErrorKind, IoResult};
|
||||||
|
@ -13,7 +13,7 @@ use data::kinds::{IrcReader, IrcWriter};
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
/// Trait describing core Server functionality.
|
/// Trait describing core Server functionality.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub trait Server<'a, T, U> {
|
pub trait Server<'a, T, U> {
|
||||||
/// Gets the configuration being used with this Server.
|
/// Gets the configuration being used with this Server.
|
||||||
fn config(&self) -> &Config;
|
fn config(&self) -> &Config;
|
||||||
|
@ -26,7 +26,7 @@ pub trait Server<'a, T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A thread-safe implementation of an IRC Server connection.
|
/// A thread-safe implementation of an IRC Server connection.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub struct IrcServer<T: IrcReader, U: IrcWriter> {
|
pub struct IrcServer<T: IrcReader, U: IrcWriter> {
|
||||||
/// The thread-safe IRC connection.
|
/// The thread-safe IRC connection.
|
||||||
conn: Connection<T, U>,
|
conn: Connection<T, U>,
|
||||||
|
@ -44,14 +44,14 @@ pub type NetIrcServer = IrcServer<BufferedReader<NetStream>, BufferedWriter<NetS
|
||||||
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]
|
#[stable]
|
||||||
pub fn new(config: &str) -> IoResult<NetIrcServer> {
|
pub fn new(config: &str) -> IoResult<NetIrcServer> {
|
||||||
IrcServer::from_config(try!(Config::load_utf8(config)))
|
IrcServer::from_config(try!(Config::load_utf8(config)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new IRC server connection from the specified configuration, connecting
|
/// Creates a new IRC server connection from the specified configuration, connecting
|
||||||
/// immediately.
|
/// immediately.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn from_config(config: Config) -> IoResult<NetIrcServer> {
|
pub fn from_config(config: Config) -> IoResult<NetIrcServer> {
|
||||||
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())
|
||||||
|
@ -63,7 +63,7 @@ impl IrcServer<BufferedReader<NetStream>, BufferedWriter<NetStream>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reconnects to the IRC server.
|
/// Reconnects to the IRC server.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
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())
|
||||||
}
|
}
|
||||||
|
@ -95,20 +95,19 @@ impl<'a, T: IrcReader, U: IrcWriter> Server<'a, T, U> for IrcServer<T, U> {
|
||||||
|
|
||||||
impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
/// 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]
|
#[stable]
|
||||||
pub fn from_connection(config: Config, conn: Connection<T, U>) -> IrcServer<T, U> {
|
pub fn from_connection(config: Config, conn: Connection<T, U>) -> IrcServer<T, U> {
|
||||||
IrcServer { conn: conn, config: config, chanlists: Mutex::new(HashMap::new()),
|
IrcServer { conn: conn, config: config, chanlists: Mutex::new(HashMap::new()),
|
||||||
alt_nick_index: RwLock::new(0) }
|
alt_nick_index: RwLock::new(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to the IRC server's connection.
|
/// Gets a reference to the IRC server's connection.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn conn(&self) -> &Connection<T, U> {
|
pub fn conn(&self) -> &Connection<T, U> {
|
||||||
&self.conn
|
&self.conn
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles messages internally for basic bot functionality.
|
/// Handles messages internally for basic bot functionality.
|
||||||
#[experimental]
|
|
||||||
fn handle_message(&self, msg: &Message) {
|
fn handle_message(&self, msg: &Message) {
|
||||||
if let Some(resp) = Response::from_message(msg) {
|
if let Some(resp) = Response::from_message(msg) {
|
||||||
if resp == Response::RPL_NAMREPLY {
|
if resp == Response::RPL_NAMREPLY {
|
||||||
|
@ -179,7 +178,6 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles CTCP requests if the CTCP feature is enabled.
|
/// Handles CTCP requests if the CTCP feature is enabled.
|
||||||
#[experimental]
|
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
fn handle_ctcp(&self, msg: &Message) {
|
fn handle_ctcp(&self, msg: &Message) {
|
||||||
let source = match msg.prefix {
|
let source = match msg.prefix {
|
||||||
|
@ -220,31 +218,26 @@ impl<T: IrcReader, U: IrcWriter> IrcServer<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a CTCP-escaped message.
|
/// Sends a CTCP-escaped message.
|
||||||
#[experimental]
|
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
fn send_ctcp(&self, target: &str, msg: &str) {
|
fn send_ctcp(&self, target: &str, msg: &str) {
|
||||||
self.send(Command::NOTICE(target, &format!("\u{001}{}\u{001}", msg)[])).unwrap();
|
self.send(Command::NOTICE(target, &format!("\u{001}{}\u{001}", msg)[])).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles CTCP requests if the CTCP feature is enabled.
|
/// Handles CTCP requests if the CTCP feature is enabled.
|
||||||
#[experimental]
|
#[cfg(not(feature = "ctcp"))] fn handle_ctcp(&self, _: &Message) {}
|
||||||
#[cfg(not(feature = "ctcp"))]
|
|
||||||
fn handle_ctcp(&self, _: &Message) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An Iterator over an IrcServer's incoming Messages.
|
/// An Iterator over an IrcServer's incoming Messages.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub struct ServerIterator<'a, T: IrcReader, U: IrcWriter> {
|
pub struct ServerIterator<'a, T: IrcReader, U: IrcWriter> {
|
||||||
server: &'a IrcServer<T, U>
|
server: &'a IrcServer<T, U>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: IrcReader, U: IrcWriter> ServerIterator<'a, T, U> {
|
impl<'a, T: IrcReader, U: IrcWriter> ServerIterator<'a, T, U> {
|
||||||
/// Creates a new ServerIterator for the desired IrcServer.
|
/// Creates a new ServerIterator for the desired IrcServer.
|
||||||
#[experimental]
|
#[experimental = "Design will change to accomodate new behavior."]
|
||||||
pub fn new(server: &IrcServer<T, U>) -> ServerIterator<T, U> {
|
pub fn new(server: &IrcServer<T, U>) -> ServerIterator<T, U> {
|
||||||
ServerIterator {
|
ServerIterator { server: server }
|
||||||
server: server
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the next line from the connection.
|
/// Gets the next line from the connection.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Utilities and shortcuts for working with IRC servers.
|
//! Utilities and shortcuts for working with IRC servers.
|
||||||
#![experimental]
|
#![stable]
|
||||||
|
|
||||||
use std::io::IoResult;
|
use std::io::IoResult;
|
||||||
use data::{Command, Config, User};
|
use data::{Command, Config, User};
|
||||||
|
@ -12,7 +12,7 @@ use server::{Server, ServerIterator};
|
||||||
|
|
||||||
/// Functionality-providing wrapper for Server.
|
/// Functionality-providing wrapper for Server.
|
||||||
/// Wrappers are currently not thread-safe, and should be created per-thread, as needed.
|
/// Wrappers are currently not thread-safe, and should be created per-thread, as needed.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub struct Wrapper<'a, T: IrcReader, U: IrcWriter> {
|
pub struct Wrapper<'a, T: IrcReader, U: IrcWriter> {
|
||||||
server: &'a (Server<'a, T, U> + 'a)
|
server: &'a (Server<'a, T, U> + 'a)
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,13 @@ impl<'a, T: IrcReader, U: IrcWriter> Server<'a, T, U> for Wrapper<'a, T, U> {
|
||||||
|
|
||||||
impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
/// Creates a new Wrapper from the given Server.
|
/// Creates a new Wrapper from the given Server.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn new(server: &'a Server<'a, T, U>) -> Wrapper<'a, T, U> {
|
pub fn new(server: &'a Server<'a, T, U>) -> Wrapper<'a, T, U> {
|
||||||
Wrapper { server: server }
|
Wrapper { server: server }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a NICK and USER to identify.
|
/// Sends a NICK and USER to identify.
|
||||||
#[experimental]
|
#[unstable = "Capabilities requests may be moved outside of identify."]
|
||||||
pub fn identify(&self) -> IoResult<()> {
|
pub fn identify(&self) -> IoResult<()> {
|
||||||
// We'll issue a CAP REQ for multi-prefix support to improve access level tracking.
|
// We'll issue a CAP REQ for multi-prefix support to improve access level tracking.
|
||||||
try!(self.server.send(CAP(REQ, Some("multi-prefix"))));
|
try!(self.server.send(CAP(REQ, Some("multi-prefix"))));
|
||||||
|
@ -58,25 +58,25 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a PONG with the specified message.
|
/// Sends a PONG with the specified message.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_pong(&self, msg: &str) -> IoResult<()> {
|
pub fn send_pong(&self, msg: &str) -> IoResult<()> {
|
||||||
self.server.send(PONG(msg, None))
|
self.server.send(PONG(msg, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Joins the specified channel or chanlist.
|
/// Joins the specified channel or chanlist.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_join(&self, chanlist: &str) -> IoResult<()> {
|
pub fn send_join(&self, chanlist: &str) -> IoResult<()> {
|
||||||
self.server.send(JOIN(chanlist, None))
|
self.server.send(JOIN(chanlist, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to oper up using the specified username and password.
|
/// Attempts to oper up using the specified username and password.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_oper(&self, username: &str, password: &str) -> IoResult<()> {
|
pub fn send_oper(&self, username: &str, password: &str) -> IoResult<()> {
|
||||||
self.server.send(OPER(username, password))
|
self.server.send(OPER(username, password))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a message to the specified target.
|
/// Sends a message to the specified target.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_privmsg(&self, target: &str, message: &str) -> IoResult<()> {
|
pub fn send_privmsg(&self, target: &str, message: &str) -> IoResult<()> {
|
||||||
for line in message.split_str("\r\n") {
|
for line in message.split_str("\r\n") {
|
||||||
try!(self.server.send(PRIVMSG(target, line)))
|
try!(self.server.send(PRIVMSG(target, line)))
|
||||||
|
@ -85,7 +85,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a notice to the specified target.
|
/// Sends a notice to the specified target.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_notice(&self, target: &str, message: &str) -> IoResult<()> {
|
pub fn send_notice(&self, target: &str, message: &str) -> IoResult<()> {
|
||||||
for line in message.split_str("\r\n") {
|
for line in message.split_str("\r\n") {
|
||||||
try!(self.server.send(NOTICE(target, line)))
|
try!(self.server.send(NOTICE(target, line)))
|
||||||
|
@ -95,7 +95,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sets the topic of a channel or requests the current one.
|
/// 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.
|
/// If `topic` is an empty string, it won't be included in the message.
|
||||||
#[experimental]
|
#[unstable = "Design may change."]
|
||||||
pub fn send_topic(&self, channel: &str, topic: &str) -> IoResult<()> {
|
pub fn send_topic(&self, channel: &str, topic: &str) -> IoResult<()> {
|
||||||
self.server.send(TOPIC(channel, if topic.len() == 0 {
|
self.server.send(TOPIC(channel, if topic.len() == 0 {
|
||||||
None
|
None
|
||||||
|
@ -105,7 +105,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kills the target with the provided message.
|
/// Kills the target with the provided message.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_kill(&self, target: &str, message: &str) -> IoResult<()> {
|
pub fn send_kill(&self, target: &str, message: &str) -> IoResult<()> {
|
||||||
self.server.send(KILL(target, message))
|
self.server.send(KILL(target, message))
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Changes the mode of the target.
|
/// Changes the mode of the target.
|
||||||
/// If `modeparmas` is an empty string, it won't be included in the message.
|
/// If `modeparmas` is an empty string, it won't be included in the message.
|
||||||
#[experimental]
|
#[unstable = "Design may change."]
|
||||||
pub fn send_mode(&self, target: &str, mode: &str, modeparams: &str) -> IoResult<()> {
|
pub fn send_mode(&self, target: &str, mode: &str, modeparams: &str) -> IoResult<()> {
|
||||||
self.server.send(MODE(target, mode, if modeparams.len() == 0 {
|
self.server.send(MODE(target, mode, if modeparams.len() == 0 {
|
||||||
None
|
None
|
||||||
|
@ -134,7 +134,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Changes the mode of the target by force.
|
/// Changes the mode of the target by force.
|
||||||
/// If `modeparams` is an empty string, it won't be included in the message.
|
/// If `modeparams` is an empty string, it won't be included in the message.
|
||||||
#[experimental]
|
#[unstable = "Design may change."]
|
||||||
pub fn send_samode(&self, target: &str, mode: &str, modeparams: &str) -> IoResult<()> {
|
pub fn send_samode(&self, target: &str, mode: &str, modeparams: &str) -> IoResult<()> {
|
||||||
self.server.send(SAMODE(target, mode, if modeparams.len() == 0 {
|
self.server.send(SAMODE(target, mode, if modeparams.len() == 0 {
|
||||||
None
|
None
|
||||||
|
@ -144,20 +144,20 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Forces a user to change from the old nickname to the new nickname.
|
/// Forces a user to change from the old nickname to the new nickname.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_sanick(&self, old_nick: &str, new_nick: &str) -> IoResult<()> {
|
pub fn send_sanick(&self, old_nick: &str, new_nick: &str) -> IoResult<()> {
|
||||||
self.server.send(SANICK(old_nick, new_nick))
|
self.server.send(SANICK(old_nick, new_nick))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invites a user to the specified channel.
|
/// Invites a user to the specified channel.
|
||||||
#[experimental]
|
#[stable]
|
||||||
pub fn send_invite(&self, nick: &str, chan: &str) -> IoResult<()> {
|
pub fn send_invite(&self, nick: &str, chan: &str) -> IoResult<()> {
|
||||||
self.server.send(INVITE(nick, chan))
|
self.server.send(INVITE(nick, chan))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Quits the server entirely with a message.
|
/// Quits the server entirely with a message.
|
||||||
/// This defaults to `Powered by Rust.` if none is specified.
|
/// This defaults to `Powered by Rust.` if none is specified.
|
||||||
#[experimental]
|
#[unstable = "Design may change."]
|
||||||
pub fn send_quit(&self, msg: &str) -> IoResult<()> {
|
pub fn send_quit(&self, msg: &str) -> IoResult<()> {
|
||||||
self.server.send(QUIT(Some(if msg.len() == 0 {
|
self.server.send(QUIT(Some(if msg.len() == 0 {
|
||||||
"Powered by Rust."
|
"Powered by Rust."
|
||||||
|
@ -168,7 +168,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a CTCP-escaped message to the specified target.
|
/// Sends a CTCP-escaped message to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_ctcp(&self, target: &str, msg: &str) -> IoResult<()> {
|
pub fn send_ctcp(&self, target: &str, msg: &str) -> IoResult<()> {
|
||||||
self.send_privmsg(target, &format!("\u{001}{}\u{001}", msg)[])
|
self.send_privmsg(target, &format!("\u{001}{}\u{001}", msg)[])
|
||||||
|
@ -176,7 +176,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends an action command to the specified target.
|
/// Sends an action command to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_action(&self, target: &str, msg: &str) -> IoResult<()> {
|
pub fn send_action(&self, target: &str, msg: &str) -> IoResult<()> {
|
||||||
self.send_ctcp(target, &format!("ACTION {}", msg)[])
|
self.send_ctcp(target, &format!("ACTION {}", msg)[])
|
||||||
|
@ -184,7 +184,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a finger request to the specified target.
|
/// Sends a finger request to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_finger(&self, target: &str) -> IoResult<()> {
|
pub fn send_finger(&self, target: &str) -> IoResult<()> {
|
||||||
self.send_ctcp(target, "FINGER")
|
self.send_ctcp(target, "FINGER")
|
||||||
|
@ -192,7 +192,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a version request to the specified target.
|
/// Sends a version request to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_version(&self, target: &str) -> IoResult<()> {
|
pub fn send_version(&self, target: &str) -> IoResult<()> {
|
||||||
self.send_ctcp(target, "VERSION")
|
self.send_ctcp(target, "VERSION")
|
||||||
|
@ -200,7 +200,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a source request to the specified target.
|
/// Sends a source request to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_source(&self, target: &str) -> IoResult<()> {
|
pub fn send_source(&self, target: &str) -> IoResult<()> {
|
||||||
self.send_ctcp(target, "SOURCE")
|
self.send_ctcp(target, "SOURCE")
|
||||||
|
@ -208,7 +208,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a user info request to the specified target.
|
/// Sends a user info request to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_user_info(&self, target: &str) -> IoResult<()> {
|
pub fn send_user_info(&self, target: &str) -> IoResult<()> {
|
||||||
self.send_ctcp(target, "USERINFO")
|
self.send_ctcp(target, "USERINFO")
|
||||||
|
@ -216,7 +216,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a finger request to the specified target.
|
/// Sends a finger request to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_ctcp_ping(&self, target: &str) -> IoResult<()> {
|
pub fn send_ctcp_ping(&self, target: &str) -> IoResult<()> {
|
||||||
let time = get_time();
|
let time = get_time();
|
||||||
|
@ -225,7 +225,7 @@ impl<'a, T: IrcReader, U: IrcWriter> Wrapper<'a, T, U> {
|
||||||
|
|
||||||
/// Sends a time request to the specified target.
|
/// Sends a time request to the specified target.
|
||||||
/// This requires the CTCP feature to be enabled.
|
/// This requires the CTCP feature to be enabled.
|
||||||
#[experimental]
|
#[unstable = "Feature is relatively new."]
|
||||||
#[cfg(feature = "ctcp")]
|
#[cfg(feature = "ctcp")]
|
||||||
pub fn send_time(&self, target: &str) -> IoResult<()> {
|
pub fn send_time(&self, target: &str) -> IoResult<()> {
|
||||||
self.send_ctcp(target, "TIME")
|
self.send_ctcp(target, "TIME")
|
||||||
|
|
Loading…
Add table
Reference in a new issue