Files
wiktlarp-tf2/src/command/mod.rs
T
2026-08-16 01:19:07 -06:00

160 lines
4.5 KiB
Rust

use regex::{regex, Regex};
#[derive(Debug,Eq,PartialEq,Clone)]
pub struct EntryQuery<'a> {
term : &'a str,
language : Option <&'a str>,
pos : Option <&'a str>,
}
impl<'a> EntryQuery<'a> {
pub fn basic (term : &'a str) -> EntryQuery<'a> {
EntryQuery { term, language: None, pos: None }
}
}
#[derive(Debug,Eq,PartialEq,Clone)]
pub enum Command<'a> {
Define (EntryQuery<'a>),
Etymology (EntryQuery<'a>),
}
#[derive(Debug,Eq,PartialEq,Clone)]
pub struct ChatMessage<'a> {
author : &'a str,
content : &'a str,
}
impl<'a> ChatMessage<'a> {
pub fn unauthored (content : &'a str) -> ChatMessage<'a> {
ChatMessage { author: "", content }
}
pub fn parse (line : &'a str) -> Option<ChatMessage<'a>> {
let re : &Regex = regex! (r"(?:\*사망\* )?(.*?) : (.*)");
let r = re.captures (line)?;
Some (ChatMessage {
author: r.get (1)?.as_str (),
content: r.get (2)?.as_str (),
})
}
}
fn find_query<'a> (s : &'a str) -> Option<EntryQuery<'a>> {
let basic_re = regex! (r"^\s*define (.*)|define (\w+)");
let wikilink_re = regex! (r"(?m)\[\[([^]]*)]]");
let term = if let Some (r) = wikilink_re.captures (s) {
r.get (1)
} else if let Some (r) = basic_re.captures (s) {
r.get (1).or (r.get (2))
} else {
None
};
Some (EntryQuery::basic (term?.as_str ()))
}
impl<'a> Command<'a> {
pub fn parse (msg : &'a ChatMessage<'a>) -> Option<Command<'a>> {
Self::parse_str (msg.content)
}
pub fn parse_str (s : &'a str) -> Option<Command<'a>> {
Self::parse_etymology (s).or (Self::parse_define (s))
}
fn parse_define (s : &'a str) -> Option<Command<'a>> {
let basic_re = regex! (r"^\s*define (.*)|define (\w+)");
let wikilink_re = regex! (r"\[\[([^]]*)]]");
let term = if let Some (r) = wikilink_re.captures (s) {
r.get (1)
} else if let Some (r) = basic_re.captures (s) {
r.get (1).or (r.get (2))
} else {
None
};
Some (Command::Define (EntryQuery::basic (term?.as_str ())))
}
fn parse_etymology (s : &'a str) -> Option<Command<'a>> {
let basic_re = regex! (r"^\s*etymology of (.*)|ety(?:m(?:ology(?: of)?)?)? (\w+)");
let wikilink_re = regex! (r"ety(?:m(?:ology(?: of)?)?)? \[\[([^]]*)]]");
let term = if let Some (r) = wikilink_re.captures (s) {
r.get (1)
} else if let Some (r) = basic_re.captures (s) {
r.get (1).or (r.get (2))
} else {
None
};
Some (Command::Etymology (EntryQuery::basic (term?.as_str ())))
}
}
mod tests {
use super::*;
use super::Command as Cmd;
#[test]
fn etym_wikilink () {
assert_eq! (
Cmd::parse_str (
"blah blah etymology of [[lexicography]]"
),
Some (Cmd::Etymology (EntryQuery::basic ("lexicography")))
);
assert_eq! (
Cmd::parse_str (
"etym [[lexicography]]"
),
Some (Cmd::Etymology (EntryQuery::basic ("lexicography")))
);
assert_eq! (
Cmd::parse_str (
"ety [[lexicography]]"
),
Some (Cmd::Etymology (EntryQuery::basic ("lexicography")))
);
}
#[test]
fn etym_basic () {
assert_eq! (
Cmd::parse_str (
"wiktionary, can you provide the etymology of lexicography??"
),
Some (Cmd::Etymology (EntryQuery::basic ("lexicography")))
)
}
#[test]
fn define_basic () {
assert_eq! (
Cmd::parse_str ("wiktionary, can you define lexicography??"),
Some (Cmd::Define (EntryQuery::basic ("lexicography")))
);
}
#[test]
fn define_line () {
assert_eq! (
Cmd::parse_str ("define I'm twenty years old"),
Some (Cmd::Define (EntryQuery::basic ("I'm twenty years old")))
);
}
#[test]
fn define_wikilink () {
assert_eq! (
Cmd::parse_str ("[[hoofjob]]"),
Some (Cmd::Define (EntryQuery::basic ("hoofjob")))
);
assert_eq! (
Cmd::parse_str ("bkah blah blah [[quirkchungus]] blbalb"),
Some (Cmd::Define (EntryQuery::basic ("quirkchungus")))
);
assert_eq! (
Cmd::parse_str ("define I'm [[twenty]] years old"),
Some (Cmd::Define (EntryQuery::basic ("twenty")))
);
}
}