diff options
Diffstat (limited to 'src/system/message_parser.rs')
-rw-r--r-- | src/system/message_parser.rs | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/src/system/message_parser.rs b/src/system/message_parser.rs deleted file mode 100644 index 7845fbf..0000000 --- a/src/system/message_parser.rs +++ /dev/null @@ -1,238 +0,0 @@ -use std::sync::LazyLock; -use regex::{Regex, RegexBuilder}; - -use crate::config::System; - -use twilight_mention::ParseMention; -use twilight_model::id::{marker::UserMarker, Id}; -use super::{FullMessage, MemberId, MessageId, ServerId, Timestamp, UserId}; - -pub enum ParsedMessage { - Command(Command), - SetProxyAndDelete(MemberId), - ProxiedMessage { - member_id: MemberId, - message_content: String, - latch: bool, - }, - UnproxiedMessage(Option<String>), - LatchClear(MemberId), - - // TODO: Figure out how to represent emotes - EmoteAdd(MemberId, MessageId, ()), - EmoteRemove(MemberId, MessageId, ()), -} - -pub enum Command { - Part(ServerId), - Edit(MemberId, MessageId, String), - Reproxy(MemberId, MessageId), - Delete(MessageId), - Nick(MemberId, String), - Log(String), - ReloadSystemConfig, - ExitSéance, - UnknownCommand, - InvalidCommand -} - -pub struct MessageParser {} - -static CORRECTION_REGEX: LazyLock<Regex> = LazyLock::new(|| { - Regex::new(r"^\*\B+$").unwrap() -}); - -impl MessageParser { - pub fn parse(message: &FullMessage, secondary_message: Option<&FullMessage>, system_config: &System, latch_state: Option<(MemberId, Timestamp)>) -> ParsedMessage { - if message.content == r"\\" { - return ParsedMessage::LatchClear(if let Some((member_id, _)) = latch_state { - member_id - } else { - 0 - }) - } - - if message.content.starts_with(r"\") { - return ParsedMessage::UnproxiedMessage(None) - } - - if message.content.starts_with(r"!") { - if let Some(parse) = MessageParser::check_command(message, secondary_message, system_config, latch_state) { - return ParsedMessage::Command(parse); - } else { - return ParsedMessage::UnproxiedMessage(Some(format!("Unknown command string: {}", message.content))); - } - } - - if CORRECTION_REGEX.is_match(message.content.as_str()) { - if let Some(parse) = MessageParser::check_correction(message, secondary_message) { - return parse - } - } - - if let Some(parse) = MessageParser::check_member_patterns(message, secondary_message, system_config) { - return parse - } - - if let Some(parse) = MessageParser::check_autoproxy(message, latch_state) { - return parse - } - - // If nothing else - ParsedMessage::UnproxiedMessage(None) - } - - fn check_command(message: &FullMessage, secondary_message: Option<&FullMessage>, system_config: &System, latch_state: Option<(MemberId, Timestamp)>) -> Option<Command> { - let mut words = message.content.strip_prefix("!").unwrap().split_whitespace(); - let first_word = words.next(); - - match first_word { - None => return None, - Some(command_name) => match command_name { - "log" => { - let remainder = words.remainder().unwrap().to_string(); - return Some(Command::Log(remainder)); - }, - "edit" => { - let editing_member = Self::get_member_id_from_user_id(secondary_message.as_ref().unwrap().author.id, system_config).unwrap(); - return Some(Command::Edit(editing_member, secondary_message.unwrap().id, words.remainder().unwrap().to_string())); - }, - "nick" => { - if let Some(member) = MessageParser::match_member(words.next(), system_config) { - return Some(Command::Nick(member, words.remainder().unwrap().to_string())); - } - }, - "reproxy" => { - if let Some(member) = MessageParser::match_member(words.next(), system_config) { - return Some(Command::Reproxy(member, secondary_message.unwrap().id)); - } - }, - "delete" => { - return Some(Command::Delete(secondary_message.unwrap().id)); - }, - "part" => { - return Some(Command::Part(message.guild_id.unwrap())); - }, - _ => (), - }, - } - - // Attempt matching !s - if message.content.chars().nth(1).unwrap() == 's' { - let separator = message.content.chars().nth(2).unwrap(); - let parts: Vec<&str> = message.content.split(separator).collect(); - - if parts.len() != 3 && parts.len() != 4 { - return None - } - - let pattern = parts.get(1).unwrap(); - let replacement = parts.get(2).unwrap(); - let flags = parts.get(3).unwrap_or(&""); - - let mut global = false; - let mut regex = RegexBuilder::new(pattern); - - for flag in flags.chars() {match flag { - 'i' => {regex.case_insensitive(true);}, - 'm' => {regex.multi_line(true);}, - 'g' => {global = true;}, - 'x' => {regex.ignore_whitespace(true);}, - 'R' => {regex.crlf(true);}, - 's' => {regex.dot_matches_new_line(true);}, - 'U' => {regex.swap_greed(true);}, - _ => {return None;}, - }}; - - let valid_regex = regex.build(); - let original_content = &secondary_message.as_ref().unwrap().content; - - // If the regex parses, replace with that - let new_content = if let Ok(regex) = valid_regex { - if global { - regex.replace_all(original_content.as_str(), *replacement).to_string() - } else { - regex.replace(original_content.as_str(), *replacement).to_string() - } - - // Else attempt replace as string - } else { - original_content.replace(pattern, replacement) - }; - - let editing_member = Self::get_member_id_from_user_id(secondary_message.as_ref().unwrap().author.id, system_config).unwrap(); - return Some(Command::Edit(editing_member, secondary_message.as_ref().unwrap().id, new_content.to_string())); - } - - // If unable to parse - None - } - - fn check_correction(message: &FullMessage, secondary_message: Option<&FullMessage>) -> Option<ParsedMessage> { - None - } - - fn check_member_patterns(message: &FullMessage, secondary_message: Option<&FullMessage>, system_config: &System) -> Option<ParsedMessage> { - let matches_prefix = system_config.members.iter().enumerate().find_map(|(member_id, member)| - Some((member_id, member.matches_proxy_prefix(&message)?)) - ); - - if let Some((member_id, matched_content)) = matches_prefix { - if matched_content.trim() == "*" { - Some(ParsedMessage::Command(Command::Reproxy(member_id, secondary_message.unwrap().id))) - } else if matched_content.trim() != "" { - Some(ParsedMessage::ProxiedMessage { - member_id, - message_content: matched_content.to_string(), - latch: true, - }) - } else { - Some(ParsedMessage::SetProxyAndDelete(member_id)) - } - } else { - None - } - } - - fn check_autoproxy(message: &FullMessage, latch_state: Option<(MemberId, Timestamp)>) -> Option<ParsedMessage> { - if let Some((member_id, _)) = latch_state { - Some(ParsedMessage::ProxiedMessage { - member_id, - message_content: message.content.clone(), - latch: true, - }) - } else { - None - } - } - - fn match_member(maybe_mention: Option<&str>, system_config: &System) -> Option<MemberId> { - if let Some(maybe_mention) = maybe_mention { - if let Ok(mention) = Id::<UserMarker>::parse(maybe_mention) { - return MessageParser::get_member_id_from_user_id(mention, system_config) - } - } - - None - } - - pub fn get_member_id_from_user_id(user_id: UserId, system_config: &System) -> Option<MemberId> { - system_config.members.iter().enumerate() - .filter(|(_id, m)| m.user_id.is_some()) - .find(|(_id, m)| m.user_id.unwrap() == user_id) - .map(|(id, _m)| id) - } -} - -impl crate::config::Member { - pub fn matches_proxy_prefix<'a>(&self, message: &'a FullMessage) -> Option<&'a str> { - match self.message_pattern.captures(message.content.as_str()) { - None => None, - Some(captures) => match captures.name("content") { - None => None, - Some(matched_content) => Some(matched_content.as_str()), - }, - } - } -} - |