Rewrite command parsing.

This commit is contained in:
AB
2020-12-31 01:42:36 +03:00
parent 7adc629292
commit 17442819c4
3 changed files with 447 additions and 270 deletions

View File

@@ -34,3 +34,4 @@ serde_json = "1.0"
markov = "1.1.0" markov = "1.1.0"
rand = "0.7.3" rand = "0.7.3"
mystem = "0.2" mystem = "0.2"
async-trait = "0.1.42"

View File

@@ -1,5 +1,6 @@
use crate::db; use crate::db;
use crate::errors::Error; use crate::errors::Error;
use async_trait::async_trait;
use html_escape::encode_text; use html_escape::encode_text;
use markov::Chain; use markov::Chain;
use mystem::Case::Nominative; use mystem::Case::Nominative;
@@ -13,291 +14,385 @@ use regex::Regex;
use telegram_bot::prelude::*; use telegram_bot::prelude::*;
use telegram_bot::{Api, Message, ParseMode}; use telegram_bot::{Api, Message, ParseMode};
pub(crate) async fn here(api: Api, message: Message) -> Result<(), Error> { pub struct Here {
let members: Vec<telegram_bot::User> = db::get_members(message.chat.id()).unwrap(); pub data: String,
for u in &members { }
debug!("Found user {:?} in chat {}", u, message.chat.id()); pub struct Top {
} pub data: String,
let mut msg = "<b>I summon you</b>, ".to_string(); }
for user in members { pub struct MarkovAll {
let mention = match user.username { pub data: String,
Some(username) => format!("@{}", username), }
_ => format!( pub struct Markov {
"<a href=\"tg://user?id={}\">{}</a>", pub data: String,
encode_text(&user.id.to_string()), }
encode_text(&user.first_name) pub struct Omedeto {
), pub data: String,
};
msg = format!("{} {}", msg, mention);
}
match api
.send(message.text_reply(msg).parse_mode(ParseMode::Html))
.await
{
Ok(_) => debug!("/here command sent to {}", message.chat.id()),
Err(_) => warn!("/here command sent failed to {}", message.chat.id()),
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
} }
pub(crate) async fn top(api: Api, message: Message) -> Result<(), Error> { // pub enum Command {
let top = db::get_top(&message).await?; // Here(Here),
let mut msg = "<b>Your top using words:</b>\n<pre>".to_string(); // Top { data: String },
let mut counter = 1; // MarkovAll { data: String },
for word in top.iter() { // Markov { data: String },
msg = format!( // Omedeto { data: String },
"{} <b>{}</b> {} - {}\n", // }
msg, counter, word.word, word.count
); #[async_trait]
counter += 1; pub trait Execute {
} async fn run(&self, api: Api, message: Message) -> Result<(), Error>;
msg = format!("{}{}", msg, "</pre>"); async fn run_mystem(
match api &self,
.send(message.text_reply(msg).parse_mode(ParseMode::Html)) api: Api,
.await message: Message,
{ mystem: &mut MyStem,
Ok(_) => debug!("/top command sent to {}", message.chat.id()), ) -> Result<(), Error>;
Err(_) => warn!("/top command sent failed to {}", message.chat.id()),
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
} }
pub(crate) async fn markov_all(api: Api, message: Message) -> Result<(), Error> { #[async_trait]
let messages = db::get_messages_random_all().await?; impl Execute for Here {
let mut chain = Chain::new(); async fn run(&self, api: Api, message: Message) -> Result<(), Error> {
chain.feed(messages); let members: Vec<telegram_bot::User> = db::get_members(message.chat.id()).unwrap();
let mut sentences = chain.generate(); for u in &members {
let mut msg = String::new(); debug!("Found user {:?} in chat {}", u, message.chat.id());
for _ in 1..rand::thread_rng().gen_range(2, 10) { }
msg = format!("{} {}", msg, sentences.pop().unwrap()); let mut msg = "<b>I summon you</b>, ".to_string();
for user in members {
let mention = match user.username {
Some(username) => format!("@{}", username),
_ => format!(
"<a href=\"tg://user?id={}\">{}</a>",
encode_text(&user.id.to_string()),
encode_text(&user.first_name)
),
};
msg = format!("{} {}", msg, mention);
}
match api
.send(message.text_reply(msg).parse_mode(ParseMode::Html))
.await
{
Ok(_) => debug!("/here command sent to {}", message.chat.id()),
Err(_) => warn!("/here command sent failed to {}", message.chat.id()),
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
} }
match api
.send(message.text_reply(msg.trim()).parse_mode(ParseMode::Html)) async fn run_mystem(
.await &self,
{ api: Api,
Ok(_) => debug!("/markov_all command sent to {}", message.chat.id()), message: Message,
Err(_) => warn!("/markov_all command sent failed to {}", message.chat.id()), mystem: &mut MyStem,
) -> Result<(), Error> {
unimplemented!()
} }
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
} }
pub(crate) async fn markov(api: Api, message: Message) -> Result<(), Error> { #[async_trait]
let messages = db::get_messages_random_group(&message).await?; impl Execute for Top {
let mut chain = Chain::new(); async fn run(&self, api: Api, message: Message) -> Result<(), Error> {
chain.feed(messages); let top = db::get_top(&message).await?;
let mut sentences = chain.generate(); let mut msg = "<b>Your top using words:</b>\n<pre>".to_string();
let mut msg = String::new(); let mut counter = 1;
for _ in 1..rand::thread_rng().gen_range(2, 10) { for word in top.iter() {
msg = format!("{} {}", msg, sentences.pop().unwrap()); msg = format!(
"{} <b>{}</b> {} - {}\n",
msg, counter, word.word, word.count
);
counter += 1;
}
msg = format!("{}{}", msg, "</pre>");
match api
.send(message.text_reply(msg).parse_mode(ParseMode::Html))
.await
{
Ok(_) => debug!("/top command sent to {}", message.chat.id()),
Err(_) => warn!("/top command sent failed to {}", message.chat.id()),
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
} }
match api
.send(message.text_reply(msg.trim()).parse_mode(ParseMode::Html)) async fn run_mystem(
.await &self,
{ api: Api,
Ok(_) => debug!("/markov command sent to {}", message.chat.id()), message: Message,
Err(_) => warn!("/markov command sent failed to {}", message.chat.id()), mystem: &mut MyStem,
) -> Result<(), Error> {
unimplemented!()
} }
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
} }
pub(crate) async fn omedeto(api: Api, message: Message, mystem: &mut MyStem) -> Result<(), Error> { #[async_trait]
let all_msg = db::get_messages_user_all(&message).await?; impl Execute for MarkovAll {
let re = Regex::new(r"^[яЯ] [а-яА-Я]+(-[а-яА-Я]+(_[а-яА-Я]+)*)*").unwrap(); async fn run(&self, api: Api, message: Message) -> Result<(), Error> {
let mut nouns: Vec<String> = all_msg let messages = db::get_messages_random_all().await?;
.clone() let mut chain = Chain::new();
.into_iter() chain.feed(messages);
.filter(|m| re.is_match(m)) let mut sentences = chain.generate();
.map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone()) let mut msg = String::new();
.filter(|m| { for _ in 1..rand::thread_rng().gen_range(2, 10) {
let stem = mystem.stemming(m.clone()).unwrap_or_default(); msg = format!("{} {}", msg, sentences.pop().unwrap());
if stem.is_empty() { }
false match api
} else if stem[0].lex.is_empty() { .send(message.text_reply(msg.trim()).parse_mode(ParseMode::Html))
false .await
} else { {
match stem[0].lex[0].grammem.part_of_speech { Ok(_) => debug!("/markov_all command sent to {}", message.chat.id()),
mystem::PartOfSpeech::Noun => stem[0].lex[0] Err(_) => warn!("/markov_all command sent failed to {}", message.chat.id()),
.grammem }
.facts //api.send(message.chat.text("Text to message chat")).await?;
.contains(&mystem::Fact::Case(Nominative)), //api.send(message.from.text("Private text")).await?;
_ => false, Ok(())
}
}
})
.map(|w| w.replace(|z| z == '.' || z == ',', ""))
.collect();
nouns.sort();
nouns.dedup();
nouns.shuffle(&mut rand::thread_rng());
debug!("Found {} nouns. {:#?}", nouns.len(), nouns);
let mut verbs_p: Vec<String> = all_msg
.clone()
.into_iter()
.filter(|m| re.is_match(m))
.map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone())
.filter(|m| {
let stem = mystem.stemming(m.clone()).unwrap_or_default();
if stem.is_empty() {
false
} else if stem[0].lex.is_empty() {
false
} else {
match stem[0].lex[0].grammem.part_of_speech {
mystem::PartOfSpeech::Verb => stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Tense(Past)),
_ => false,
}
}
})
.map(|w| w.replace(|z| z == '.' || z == ',', ""))
.collect();
verbs_p.sort();
verbs_p.dedup();
verbs_p.shuffle(&mut rand::thread_rng());
debug!("Found {} past verbs. {:#?}", verbs_p.len(), verbs_p);
let mut verbs_i: Vec<String> = all_msg
.clone()
.into_iter()
.filter(|m| re.is_match(m))
.map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone())
.filter(|m| {
let stem = mystem.stemming(m.clone()).unwrap_or_default();
if stem.is_empty() {
false
} else if stem[0].lex.is_empty() {
false
} else {
match stem[0].lex[0].grammem.part_of_speech {
mystem::PartOfSpeech::Verb => {
stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Tense(Inpresent))
&& stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Person(First))
}
_ => false,
}
}
})
.map(|w| w.replace(|z| z == '.' || z == ',', ""))
.collect();
verbs_i.sort();
verbs_i.dedup();
verbs_i.shuffle(&mut rand::thread_rng());
debug!("Found {} inpresent verbs. {:#?}", verbs_i.len(), verbs_i);
if nouns.is_empty() {
nouns.push(message.from.first_name.to_string());
} }
let start: Vec<String> = vec![
"С новым годом".into(),
"С НГ тебя".into(),
"Поздравляю".into(),
"Поздравляю с НГ".into(),
];
let placeholders: Vec<String> = vec![
"[ДАННЫЕ УДАЛЕНЫ]".into(),
"[СЕКРЕТНО]".into(),
"[НЕТ ДАННЫХ]".into(),
"[ОШИБКА ДОСТУПА]".into(),
];
//debug!("Nouns: {:#?}", nouns);
//debug!("Verbs: {:#?}", verbs);
let fem = { async fn run_mystem(
let mut fm = 0; &self,
let mut mu = 0; api: Api,
all_msg message: Message,
mystem: &mut MyStem,
) -> Result<(), Error> {
unimplemented!()
}
}
#[async_trait]
impl Execute for Markov {
async fn run(&self, api: Api, message: Message) -> Result<(), Error> {
let messages = db::get_messages_random_group(&message).await?;
let mut chain = Chain::new();
chain.feed(messages);
let mut sentences = chain.generate();
let mut msg = String::new();
for _ in 1..rand::thread_rng().gen_range(2, 10) {
msg = format!("{} {}", msg, sentences.pop().unwrap());
}
match api
.send(message.text_reply(msg.trim()).parse_mode(ParseMode::Html))
.await
{
Ok(_) => debug!("/markov command sent to {}", message.chat.id()),
Err(_) => warn!("/markov command sent failed to {}", message.chat.id()),
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok(())
}
async fn run_mystem(
&self,
api: Api,
message: Message,
mystem: &mut MyStem,
) -> Result<(), Error> {
unimplemented!()
}
}
#[async_trait]
impl Execute for Omedeto {
async fn run(&self, api: Api, message: Message) -> Result<(), Error> {
unimplemented!()
}
async fn run_mystem(
&self,
api: Api,
message: Message,
mystem: &mut MyStem,
) -> Result<(), Error> {
let all_msg = db::get_messages_user_all(&message).await?;
let re = Regex::new(r"^[яЯ] [а-яА-Я]+(-[а-яА-Я]+(_[а-яА-Я]+)*)*").unwrap();
let mut nouns: Vec<String> = all_msg
.clone() .clone()
.into_iter() .into_iter()
.filter(|m| re.is_match(m)) .filter(|m| re.is_match(m))
.map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone()) .map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone())
.map(|m| { .filter(|m| {
let stem = mystem.stemming(m.clone()).unwrap_or_default(); let stem = mystem.stemming(m.clone()).unwrap_or_default();
if stem.is_empty() { if stem.is_empty() {
() false
} else if stem[0].lex.is_empty() { } else if stem[0].lex.is_empty() {
() false
} else { } else {
match stem[0].lex[0].grammem.part_of_speech { match stem[0].lex[0].grammem.part_of_speech {
mystem::PartOfSpeech::Verb => { mystem::PartOfSpeech::Noun => stem[0].lex[0]
match stem[0].lex[0] .grammem
.grammem .facts
.facts .contains(&mystem::Fact::Case(Nominative)),
.contains(&mystem::Fact::Tense(Past)) _ => false,
{
true => {
if stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Gender(Feminine))
{
fm = fm + 1;
} else {
mu = mu + 1;
}
}
false => (),
}
}
_ => (),
} }
} }
}) })
.collect::<()>(); .map(|w| w.replace(|z| z == '.' || z == ',', ""))
debug!("fm - {}, mu - {}", fm, mu); .collect();
if fm >= mu { nouns.sort();
true nouns.dedup();
} else { nouns.shuffle(&mut rand::thread_rng());
false //debug!("Found {} nouns. {:#?}", nouns.len(), nouns);
}
};
debug!("Is Feminine - {}", fem);
let result = format!(
"{} {} известн{} как {}, {}, а так же конечно {}. В прошедшем году ты часто давал{} нам знать, что ты {}, {} и {}. Нередко ты говорил{} я {}, я {} или даже я {}. =*",
start.choose(&mut rand::thread_rng()).unwrap(),
message.from.first_name.to_string(),
{if fem {"ая"} else {"ый"}},
nouns.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
nouns.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
nouns.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
{if fem {"а"} else {""}},
verbs_p.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_p.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_p.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
{if fem {"а"} else {""}},
verbs_i.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_i.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_i.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
); let mut verbs_p: Vec<String> = all_msg
debug!("{:?}", result); .clone()
match api .into_iter()
.send( .filter(|m| re.is_match(m))
message .map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone())
.text_reply(result.trim()) .filter(|m| {
.parse_mode(ParseMode::Html), let stem = mystem.stemming(m.clone()).unwrap_or_default();
) if stem.is_empty() {
.await false
{ } else if stem[0].lex.is_empty() {
Ok(_) => debug!("/omedeto command sent to {}", message.chat.id()), false
Err(_) => warn!("/omedeto command sent failed to {}", message.chat.id()), } else {
match stem[0].lex[0].grammem.part_of_speech {
mystem::PartOfSpeech::Verb => stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Tense(Past)),
_ => false,
}
}
})
.map(|w| w.replace(|z| z == '.' || z == ',', ""))
.collect();
verbs_p.sort();
verbs_p.dedup();
verbs_p.shuffle(&mut rand::thread_rng());
//debug!("Found {} past verbs. {:#?}", verbs_p.len(), verbs_p);
let mut verbs_i: Vec<String> = all_msg
.clone()
.into_iter()
.filter(|m| re.is_match(m))
.map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone())
.filter(|m| {
let stem = mystem.stemming(m.clone()).unwrap_or_default();
if stem.is_empty() {
false
} else if stem[0].lex.is_empty() {
false
} else {
match stem[0].lex[0].grammem.part_of_speech {
mystem::PartOfSpeech::Verb => {
stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Tense(Inpresent))
&& stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Person(First))
}
_ => false,
}
}
})
.map(|w| w.replace(|z| z == '.' || z == ',', ""))
.collect();
verbs_i.sort();
verbs_i.dedup();
verbs_i.shuffle(&mut rand::thread_rng());
//debug!("Found {} inpresent verbs. {:#?}", verbs_i.len(), verbs_i);
if nouns.is_empty() {
nouns.push(message.from.first_name.to_string());
}
let start: Vec<String> = vec![
"С новым годом".into(),
"С НГ тебя".into(),
"Поздравляю".into(),
"Поздравляю с НГ".into(),
];
let placeholders: Vec<String> = vec![
"[ДАННЫЕ УДАЛЕНЫ]".into(),
"[СЕКРЕТНО]".into(),
"[НЕТ ДАННЫХ]".into(),
"[ОШИБКА ДОСТУПА]".into(),
];
//debug!("Nouns: {:#?}", nouns);
//debug!("Verbs: {:#?}", verbs);
let fem = {
let mut fm = 0;
let mut mu = 0;
all_msg
.clone()
.into_iter()
.filter(|m| re.is_match(m))
.map(|m| m.split(' ').map(|s| s.to_string()).collect::<Vec<String>>()[1].clone())
.map(|m| {
let stem = mystem.stemming(m.clone()).unwrap_or_default();
if stem.is_empty() {
()
} else if stem[0].lex.is_empty() {
()
} else {
match stem[0].lex[0].grammem.part_of_speech {
mystem::PartOfSpeech::Verb => {
match stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Tense(Past))
{
true => {
if stem[0].lex[0]
.grammem
.facts
.contains(&mystem::Fact::Gender(Feminine))
{
fm = fm + 1;
} else {
mu = mu + 1;
}
}
false => (),
}
}
_ => (),
}
}
})
.collect::<()>();
//debug!("fm - {}, mu - {}", fm, mu);
if fm >= mu {
true
} else {
false
}
};
//debug!("Is Feminine - {}", fem);
let result = format!(
"{} {} известн{} как {}, {}, а так же конечно {}. В прошедшем году ты часто давал{} нам знать, что ты {}, {} и {}. Нередко ты говорил{} я {}, я {} или даже я {}. =*",
start.choose(&mut rand::thread_rng()).unwrap(),
message.from.first_name.to_string(),
{ if fem { "ая" } else { "ый" } },
nouns.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
nouns.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
nouns.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
{ if fem { "а" } else { "" } },
verbs_p.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_p.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_p.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
{ if fem { "а" } else { "" } },
verbs_i.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_i.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
verbs_i.pop().unwrap_or(placeholders.choose(&mut rand::thread_rng()).unwrap().to_string()),
);
//debug!("{:?}", result);
match api
.send(
message
.text_reply(result.trim())
.parse_mode(ParseMode::Html),
)
.await
{
Ok(_) => debug!("/omedeto command sent to {}", message.chat.id()),
Err(_) => warn!("/omedeto command sent failed to {}", message.chat.id()),
}
Ok(())
} }
Ok(())
} }

View File

@@ -1,11 +1,56 @@
use crate::commands; //use crate::commands::Command;
use crate::commands::{Execute, Here, Markov, MarkovAll, Omedeto, Top};
use crate::db; use crate::db;
use crate::errors; use crate::errors;
use crate::utils; use crate::utils;
use mystem::MyStem; use mystem::MyStem;
use telegram_bot::*; use telegram_bot::*;
//async fn detector() // struct Command {
// command: Commands,
// explicit: bool,
// rest: String,
// }
// async fn detector(msg: String, me: &User) -> Result<Command, ()> {
// let cleaned_message = msg.replace(&format!("@{}", me.clone().username.unwrap()), "");
// match cleaned_message.as_str() {
// "/here" => Ok(Command::Here {
// data: "".to_string(),
// }),
// s if s.contains("/here") => Ok(Command::Here {
// data: s.to_string(),
// }),
// "/top" => Ok(Command::Top {
// data: "".to_string(),
// }),
// "/stat" => Ok(Command::Top {
// data: "".to_string(),
// }),
// s if s.contains(|z| z == "/top" || z == "/stat") => Ok(Command::Top {
// data: s.to_string(),
// }),
// "/markov_all" => Ok(Command::MarkovAll {
// data: "".to_string(),
// }),
// s if s.contains("/markov_all") => Ok(Command::MarkovAll {
// data: s.to_string(),
// }),
// "/markov" => Ok(Command::Markov {
// data: "".to_string(),
// }),
// s if s.contains("/markov") => Ok(Command::Markov {
// data: s.to_string(),
// }),
// "/omedeto" => Ok(Command::Omedeto {
// data: "".to_string(),
// }),
// s if s.contains("/Omedeto") => Ok(Command::Omedeto {
// data: s.to_string(),
// }),
// _ => Err(()),
// }
// }
pub async fn handler( pub async fn handler(
api: Api, api: Api,
@@ -27,15 +72,51 @@ pub async fn handler(
); );
db::add_sentence(&message, mystem).await?; db::add_sentence(&message, mystem).await?;
let cleaned_message = data let cleaned_message = data
.to_string() .replace(&format!("@{}", me.clone().username.unwrap()), "");
.replace(&format!("@{}", me.username.unwrap()), ""); debug!("Cleaned - {}", cleaned_message);
match cleaned_message.as_str() { match cleaned_message.as_str() {
"/here" => commands::here(api, message).await?, s if s.contains("/here") => {
"/top" => commands::top(api, message).await?, Here {
"/stat" => commands::top(api, message).await?, data: "".to_string(),
"/markov_all" => commands::markov_all(api, message).await?, }
"/markov" => commands::markov(api, message).await?, .run(api, message)
"/omedeto" => commands::omedeto(api, message, mystem).await?, .await?
}
"/top" => {
Top {
data: "".to_string(),
}
.run(api, message)
.await?
}
"/stat" => {
Top {
data: "".to_string(),
}
.run(api, message)
.await?
}
"/markov_all" => {
MarkovAll {
data: "".to_string(),
}
.run(api, message)
.await?
}
"/markov" => {
MarkovAll {
data: "".to_string(),
}
.run(api, message)
.await?
}
"/omedeto" => {
Omedeto {
data: "".to_string(),
}
.run_mystem(api, message, mystem)
.await?
}
_ => (), _ => (),
} }
} }