Skip to content

Commit

Permalink
irc-proto: allow modes with no prefix
Browse files Browse the repository at this point in the history
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"
  • Loading branch information
martinetd committed Jun 23, 2023
1 parent 8eef9c5 commit 709151b
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions irc-proto/src/mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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>
Expand All @@ -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>
Expand All @@ -245,13 +250,15 @@ 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),
}
}
}

enum PlusMinus {
Plus,
Minus,
NoPrefix,
}

// MODE user [modes]
Expand Down Expand Up @@ -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
Expand All @@ -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),
})
}
}
Expand Down Expand Up @@ -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
);
}
}

0 comments on commit 709151b

Please sign in to comment.