Added support for IRCv3 batch extension.

This commit is contained in:
Aaron Weiss 2015-07-16 15:16:55 -04:00
parent 613b1c85ae
commit 2f7c7b116c
2 changed files with 94 additions and 8 deletions

View file

@ -12,10 +12,16 @@ pub enum Capability {
AwayNotify,
/// [extended-join](http://ircv3.net/specs/extensions/extended-join-3.1.html)
ExtendedJoin,
/// [metadata](http://ircv3.net/specs/core/metadata-3.2.html)
Metadata,
/// [metadata-notify](http://ircv3.net/specs/core/metadata-3.2.html)
MetadataNotify,
/// [monitor](http://ircv3.net/specs/core/monitor-3.2.html)
Monitor,
/// [account-tag](http://ircv3.net/specs/extensions/account-tag-3.2.html)
AccountTag,
/// [batch](http://ircv3.net/specs/extensions/batch-3.2.html)
Batch,
/// [cap-notify](http://ircv3.net/specs/extensions/cap-notify-3.2.html)
CapNotify,
/// [chghost](http://ircv3.net/specs/extensions/chghost-3.2.html)
@ -28,10 +34,6 @@ pub enum Capability {
ServerTime,
/// [userhost-in-names](http://ircv3.net/specs/extensions/userhost-in-names-3.2.html)
UserhostInNames,
/// [metadata](http://ircv3.net/specs/core/metadata-3.2.html)
Metadata,
/// [metadata-notify](http://ircv3.net/specs/core/metadata-3.2.html)
MetadataNotify,
/// Custom IRCv3 capability extensions
Custom(&'static str),
}
@ -51,16 +53,17 @@ impl AsRef<str> for Capability {
Capability::AccountNotify => "account-notify",
Capability::AwayNotify => "away-notify",
Capability::ExtendedJoin => "extended-join",
Capability::Metadata => "metadata",
Capability::MetadataNotify => "metadata-notify",
Capability::Monitor => "monitor",
Capability::AccountTag => "account-tag",
Capability::Batch => "batch",
Capability::CapNotify => "cap-notify",
Capability::ChgHost => "chghost",
Capability::EchoMessage => "echo-message",
Capability::InviteNotify => "invite-notify",
Capability::ServerTime => "server-time",
Capability::UserhostInNames => "userhost-in-names",
Capability::Metadata => "metadata",
Capability::MetadataNotify => "metadata-notify",
Capability::Custom(s) => s,
}
}
@ -76,16 +79,17 @@ mod test {
assert_eq!(AccountNotify.as_ref(), "account-notify");
assert_eq!(AwayNotify.as_ref(), "away-notify");
assert_eq!(ExtendedJoin.as_ref(), "extended-join");
assert_eq!(Metadata.as_ref(), "metadata");
assert_eq!(MetadataNotify.as_ref(), "metadata-notify");
assert_eq!(Monitor.as_ref(), "monitor");
assert_eq!(AccountTag.as_ref(), "account-tag");
assert_eq!(Batch.as_ref(), "batch");
assert_eq!(CapNotify.as_ref(), "cap-notify");
assert_eq!(ChgHost.as_ref(), "chghost");
assert_eq!(EchoMessage.as_ref(), "echo-message");
assert_eq!(InviteNotify.as_ref(), "invite-notify");
assert_eq!(ServerTime.as_ref(), "server-time");
assert_eq!(UserhostInNames.as_ref(), "userhost-in-names");
assert_eq!(Metadata.as_ref(), "metadata");
assert_eq!(MetadataNotify.as_ref(), "metadata-notify");
assert_eq!(Custom("example").as_ref(), "example");
}
}

View file

@ -161,6 +161,8 @@ pub enum Command {
METADATA(String, Option<MetadataSubCommand>, Option<Vec<String>>, Option<String>),
/// MONITOR command [nicklist]
MONITOR(String, Option<String>),
/// BATCH (+/-)reference-tag [type [params]]
BATCH(String, Option<BatchSubCommand>, Option<Vec<String>>),
/// CHGHOST user host
CHGHOST(String, String),
}
@ -349,6 +351,18 @@ impl Into<Message> for Command {
Message::from_owned(None, string("MONITOR"), Some(vec![c, t]), None),
Command::MONITOR(c, None) =>
Message::from_owned(None, string("MONITOR"), Some(vec![c]), None),
Command::BATCH(t, Some(c), Some(a)) =>
Message::from_owned(None, string("BATCH"), Some(vec![t, c.string()].into_iter()
.chain(a)
.collect()),
None),
Command::BATCH(t, Some(c), None) =>
Message::from_owned(None, string("BATCH"), Some(vec![t, c.string()]), None),
Command::BATCH(t, None, Some(a)) =>
Message::from_owned(None, string("BATCH"),
Some(vec![t].into_iter().chain(a).collect()), None),
Command::BATCH(t, None, None) =>
Message::from_owned(None, string("BATCH"), Some(vec![t]), None),
Command::CHGHOST(u, h) =>
Message::from_owned(None, string("CHGHOST"), Some(vec![u, h]), None),
}
@ -1125,6 +1139,37 @@ impl<'a> From<&'a Message> for Result<Command> {
} else {
return Err(invalid_input())
}
} else if let "BATCH" = &m.command[..] {
match m.suffix {
Some(ref suffix) => if m.args.len() == 0 {
Command::BATCH(suffix.clone(), None, None)
} else if m.args.len() == 1 {
Command::BATCH(m.args[0].clone(), Some(
suffix.parse().unwrap_or(return Err(invalid_input()))
), None)
} else if m.args.len() > 1 {
Command::BATCH(m.args[0].clone(), Some(
m.args[1].parse().unwrap_or(return Err(invalid_input()))
), Some(
vec![suffix.clone()].into_iter().chain(m.args[2..].to_owned()).collect()
))
} else {
return Err(invalid_input())
},
None => if m.args.len() == 1 {
Command::BATCH(m.args[0].clone(), None, None)
} else if m.args.len() == 2 {
Command::BATCH(m.args[0].clone(), Some(
m.args[1].parse().unwrap_or(return Err(invalid_input()))
), None)
} else if m.args.len() > 2 {
Command::BATCH(m.args[0].clone(), Some(
m.args[1].parse().unwrap_or(return Err(invalid_input()))
), Some(m.args[2..].to_owned()))
} else {
return Err(invalid_input())
}
}
} else if let "CHGHOST" = &m.command[..] {
match m.suffix {
Some(ref suffix) => if m.args.len() == 1 {
@ -1254,6 +1299,43 @@ impl FromStr for MetadataSubCommand {
}
}
/// [batch extension](http://ircv3.net/specs/extensions/batch-3.2.html).
#[derive(Clone, Debug, PartialEq)]
pub enum BatchSubCommand {
/// [NETSPLIT](http://ircv3.net/specs/extensions/batch/netsplit.html)
NETSPLIT,
/// [NETJOIN](http://ircv3.net/specs/extensions/batch/netsplit.html)
NETJOIN,
/// Vendor-specific BATCH subcommands.
CUSTOM(String),
}
impl BatchSubCommand {
/// Gets the string that corresponds to this subcommand.
pub fn to_str(&self) -> &str {
match self {
&BatchSubCommand::NETSPLIT => "NETSPLIT",
&BatchSubCommand::NETJOIN => "NETJOIN",
&BatchSubCommand::CUSTOM(ref s) => &s,
}
}
// This makes some earlier lines shorter.
fn string(&self) -> String {
self.to_str().to_owned()
}
}
impl FromStr for BatchSubCommand {
type Err = &'static str;
fn from_str(s: &str) -> StdResult<BatchSubCommand, &'static str> {
match s {
"NETSPLIT" => Ok(BatchSubCommand::NETSPLIT),
"NETJOIN" => Ok(BatchSubCommand::NETJOIN),
_ => Ok(BatchSubCommand::CUSTOM(s.to_owned())),
}
}
}
/// Produces an invalid_input IoError.
fn invalid_input() -> Error {