use serde::{Deserialize, Serialize};
fn is_at_mention_space(c: char) -> bool {
matches!(c, ' ' | '\u{00a0}')
}
fn remove_at_mentions(input: &str) -> String {
let mut output = String::with_capacity(input.len());
let mut rest = input;
while let Some(start) = rest.find("<@!") {
output.push_str(&rest[..start]);
let after_marker = &rest[start + 3..];
let digit_len = after_marker
.chars()
.take_while(|c| c.is_ascii_digit())
.map(char::len_utf8)
.sum::<usize>();
if digit_len > 0 && after_marker[digit_len..].starts_with('>') {
rest = &after_marker[digit_len + 1..];
} else {
output.push_str("<@!");
rest = after_marker;
}
}
output.push_str(rest);
output
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct CMD {
pub cmd: String,
pub content: String,
}
pub fn mention_user(user_id: impl std::fmt::Display) -> String {
format!("<@{user_id}>")
}
#[allow(non_snake_case)]
pub fn MentionUser(user_id: impl std::fmt::Display) -> String {
mention_user(user_id)
}
pub fn mention_all_user() -> &'static str {
"@everyone"
}
#[allow(non_snake_case)]
pub fn MentionAllUser() -> &'static str {
mention_all_user()
}
pub fn mention_channel(channel_id: impl std::fmt::Display) -> String {
format!("<#{channel_id}>")
}
#[allow(non_snake_case)]
pub fn MentionChannel(channel_id: impl std::fmt::Display) -> String {
mention_channel(channel_id)
}
pub fn emoji(id: impl std::fmt::Display) -> String {
format!("<emoji:{id}>")
}
#[allow(non_snake_case)]
pub fn Emoji(id: impl std::fmt::Display) -> String {
emoji(id)
}
#[allow(non_snake_case)]
pub fn ETLInput(input: &str) -> String {
remove_at_mentions(input)
.trim_matches(is_at_mention_space)
.to_string()
}
pub fn parse_command(input: &str) -> CMD {
let cleaned = ETLInput(input);
match cleaned.split_once(' ') {
Some((cmd, content)) => CMD {
cmd: cmd.trim_matches(is_at_mention_space).to_string(),
content: content.to_string(),
},
None => CMD {
cmd: cleaned.trim_matches(is_at_mention_space).to_string(),
content: String::new(),
},
}
}
#[allow(non_snake_case)]
pub fn ParseCommand(input: &str) -> CMD {
parse_command(input)
}