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::error::MessageParseError;
|
||||
use crate::error::MessageParseError::InvalidModeString;
|
||||
use crate::error::ModeParseError::*;
|
||||
|
||||
/// A marker trait for different kinds of Modes.
|
||||
pub trait ModeType: fmt::Display + fmt::Debug + Clone + PartialEq {
|
||||
|
@ -218,6 +216,8 @@ where
|
|||
Plus(T, Option<String>),
|
||||
/// Removing the specified mode, optionally with an argument.
|
||||
Minus(T, Option<String>),
|
||||
/// No prefix mode, used to query ban list on channel join.
|
||||
NoPrefix(T),
|
||||
}
|
||||
|
||||
impl<T> Mode<T>
|
||||
|
@ -233,6 +233,11 @@ where
|
|||
pub fn minus(inner: T, arg: Option<&str>) -> Mode<T> {
|
||||
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>
|
||||
|
@ -245,6 +250,7 @@ where
|
|||
Mode::Minus(ref mode, Some(ref arg)) => write!(f, "-{} {}", mode, arg),
|
||||
Mode::Plus(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 {
|
||||
Plus,
|
||||
Minus,
|
||||
NoPrefix,
|
||||
}
|
||||
|
||||
// MODE user [modes]
|
||||
|
@ -287,11 +294,10 @@ where
|
|||
let mut cur_mod = match modes.next() {
|
||||
Some('+') => Plus,
|
||||
Some('-') => Minus,
|
||||
Some(c) => {
|
||||
return Err(InvalidModeString {
|
||||
string: pieces.join(" "),
|
||||
cause: InvalidModeModifier { modifier: c },
|
||||
})
|
||||
Some(_) => {
|
||||
// rewind modes
|
||||
modes = first.chars();
|
||||
NoPrefix
|
||||
}
|
||||
None => {
|
||||
// No modifier
|
||||
|
@ -314,6 +320,7 @@ where
|
|||
res.push(match cur_mod {
|
||||
Plus => Mode::Plus(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;
|
||||
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…
Reference in a new issue