From be7b7d32337a908829814e2ee417bb33cff570a0 Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Thu, 21 May 2015 22:32:23 -0400 Subject: [PATCH] Added Capability for a type-safe IRCv3 CAP REQ API. --- src/client/data/caps.rs | 31 +++++++++++++++++++++++++++++++ src/client/data/mod.rs | 2 ++ src/client/mod.rs | 2 +- src/client/server/utils.rs | 9 +++++++-- 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/client/data/caps.rs diff --git a/src/client/data/caps.rs b/src/client/data/caps.rs new file mode 100644 index 0000000..b310644 --- /dev/null +++ b/src/client/data/caps.rs @@ -0,0 +1,31 @@ +//! Enumeration of all supported IRCv3 capability extensions. + +/// List of all supported IRCv3 capability extensions from the +/// [IRCv3 specifications](http://ircv3.net/irc/). +#[derive(Debug, PartialEq)] +pub enum Capability { + /// [multi-prefix](http://ircv3.net/specs/extensions/multi-prefix-3.1.html) + MultiPrefix, + /// [account-notify](http://ircv3.net/specs/extensions/account-notify-3.1.html) + AccountNotify, +} + +impl AsRef for Capability { + fn as_ref(&self) -> &str { + match *self { + Capability::MultiPrefix => "multi-prefix", + Capability::AccountNotify => "account-notify", + } + } +} + +#[cfg(test)] +mod test { + use super::Capability::*; + + #[test] + fn to_str() { + assert_eq!(MultiPrefix.as_ref(), "multi-prefix"); + assert_eq!(AccountNotify.as_ref(), "account-notify"); + } +} diff --git a/src/client/data/mod.rs b/src/client/data/mod.rs index 22bbe96..eddba9d 100644 --- a/src/client/data/mod.rs +++ b/src/client/data/mod.rs @@ -1,5 +1,6 @@ //! Data related to IRC functionality. +pub use client::data::caps::Capability; pub use client::data::command::Command; pub use client::data::config::Config; pub use client::data::message::Message; @@ -18,6 +19,7 @@ pub mod kinds { impl IrcRead for T where T: BufRead + Sized + Send + 'static {} } +pub mod caps; pub mod command; pub mod config; pub mod message; diff --git a/src/client/mod.rs b/src/client/mod.rs index bc02e81..08b1e4f 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -8,7 +8,7 @@ pub mod prelude { //! A client-side IRC prelude, re-exporting all the necessary basics. pub use client::server::{IrcServer, Server}; pub use client::server::utils::ServerExt; - pub use client::data::{Command, Config, Message, Response}; + pub use client::data::{Capability, Command, Config, Message, Response}; pub use client::data::kinds::{IrcRead, IrcWrite}; } diff --git a/src/client/server/utils.rs b/src/client/server/utils.rs index 2ace5db..922c876 100644 --- a/src/client/server/utils.rs +++ b/src/client/server/utils.rs @@ -1,6 +1,7 @@ //! Utilities and shortcuts for working with IRC servers. use std::io::Result; use std::borrow::ToOwned; +use client::data::Capability; 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}; @@ -11,8 +12,12 @@ use client::server::Server; /// Extensions for Server capabilities that make it easier to work directly with the protocol. pub trait ServerExt<'a, T, U>: Server<'a, T, U> { /// Sends an IRCv3 capabilities request for the specified extensions. - fn send_cap_req(&self, extensions: &str) -> Result<()> { - self.send(CAP(None, REQ, None, Some(extensions.to_owned()))) + fn send_cap_req(&self, extensions: &[Capability]) -> Result<()> { + let append = |mut s: String, c| { s.push_str(c); s.push(' '); s }; + let mut exts = extensions.iter().map(|c| c.as_ref()).fold(String::new(), append); + let len = exts.len() - 1; + exts.truncate(len); + self.send(CAP(None, REQ, None, Some(exts))) } /// Sends a CAP END, NICK and USER to identify.