irc-proto: allow modes with no prefix
irc clients can query the details of some modes (e.g. request list of banned users) by sending a message with no plus or minus prefix, e.g. "MODE #chan b"
This commit is contained in:
parent
8eef9c5688
commit
709151b94d
1 changed files with 23 additions and 7 deletions
|
@ -3,8 +3,6 @@ use std::fmt;
|
||||||
|
|
||||||
use crate::command::Command;
|
use crate::command::Command;
|
||||||
use crate::error::MessageParseError;
|
use crate::error::MessageParseError;
|
||||||
use crate::error::MessageParseError::InvalidModeString;
|
|
||||||
use crate::error::ModeParseError::*;
|
|
||||||
|
|
||||||
/// A marker trait for different kinds of Modes.
|
/// A marker trait for different kinds of Modes.
|
||||||
pub trait ModeType: fmt::Display + fmt::Debug + Clone + PartialEq {
|
pub trait ModeType: fmt::Display + fmt::Debug + Clone + PartialEq {
|
||||||
|
@ -218,6 +216,8 @@ where
|
||||||
Plus(T, Option<String>),
|
Plus(T, Option<String>),
|
||||||
/// Removing the specified mode, optionally with an argument.
|
/// Removing the specified mode, optionally with an argument.
|
||||||
Minus(T, Option<String>),
|
Minus(T, Option<String>),
|
||||||
|
/// No prefix mode, used to query ban list on channel join.
|
||||||
|
NoPrefix(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Mode<T>
|
impl<T> Mode<T>
|
||||||
|
@ -233,6 +233,11 @@ where
|
||||||
pub fn minus(inner: T, arg: Option<&str>) -> Mode<T> {
|
pub fn minus(inner: T, arg: Option<&str>) -> Mode<T> {
|
||||||
Mode::Minus(inner, arg.map(|s| s.to_owned()))
|
Mode::Minus(inner, arg.map(|s| s.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a no prefix mode with an `&str` argument.
|
||||||
|
pub fn no_prefix(inner: T) -> Mode<T> {
|
||||||
|
Mode::NoPrefix(inner)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Display for Mode<T>
|
impl<T> fmt::Display for Mode<T>
|
||||||
|
@ -245,6 +250,7 @@ where
|
||||||
Mode::Minus(ref mode, Some(ref arg)) => write!(f, "-{} {}", mode, arg),
|
Mode::Minus(ref mode, Some(ref arg)) => write!(f, "-{} {}", mode, arg),
|
||||||
Mode::Plus(ref mode, None) => write!(f, "+{}", mode),
|
Mode::Plus(ref mode, None) => write!(f, "+{}", mode),
|
||||||
Mode::Minus(ref mode, None) => write!(f, "-{}", mode),
|
Mode::Minus(ref mode, None) => write!(f, "-{}", mode),
|
||||||
|
Mode::NoPrefix(ref mode) => write!(f, "{}", mode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,6 +258,7 @@ where
|
||||||
enum PlusMinus {
|
enum PlusMinus {
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
|
NoPrefix,
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODE user [modes]
|
// MODE user [modes]
|
||||||
|
@ -287,11 +294,10 @@ where
|
||||||
let mut cur_mod = match modes.next() {
|
let mut cur_mod = match modes.next() {
|
||||||
Some('+') => Plus,
|
Some('+') => Plus,
|
||||||
Some('-') => Minus,
|
Some('-') => Minus,
|
||||||
Some(c) => {
|
Some(_) => {
|
||||||
return Err(InvalidModeString {
|
// rewind modes
|
||||||
string: pieces.join(" "),
|
modes = first.chars();
|
||||||
cause: InvalidModeModifier { modifier: c },
|
NoPrefix
|
||||||
})
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// No modifier
|
// No modifier
|
||||||
|
@ -314,6 +320,7 @@ where
|
||||||
res.push(match cur_mod {
|
res.push(match cur_mod {
|
||||||
Plus => Mode::Plus(mode, arg.map(|s| s.to_string())),
|
Plus => Mode::Plus(mode, arg.map(|s| s.to_string())),
|
||||||
Minus => Mode::Minus(mode, arg.map(|s| s.to_string())),
|
Minus => Mode::Minus(mode, arg.map(|s| s.to_string())),
|
||||||
|
NoPrefix => Mode::NoPrefix(mode),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,4 +357,13 @@ mod test {
|
||||||
let cmd = "MODE #foo".parse::<Message>().unwrap().command;
|
let cmd = "MODE #foo".parse::<Message>().unwrap().command;
|
||||||
assert_eq!(Command::ChannelMODE("#foo".to_string(), vec![]), cmd);
|
assert_eq!(Command::ChannelMODE("#foo".to_string(), vec![]), cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_no_plus() {
|
||||||
|
let cmd = "MODE #foo b".parse::<Message>().unwrap().command;
|
||||||
|
assert_eq!(
|
||||||
|
Command::ChannelMODE("#foo".to_string(), vec![Mode::NoPrefix(ChannelMode::Ban)]),
|
||||||
|
cmd
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue