125 lines
3.4 KiB
Rust
125 lines
3.4 KiB
Rust
use crate::bot::{Command, Context};
|
|
use crate::database::Quote;
|
|
use async_trait::async_trait;
|
|
use std::fmt::Write;
|
|
|
|
pub struct Grab;
|
|
pub struct Quot;
|
|
|
|
pub struct Search {
|
|
limit: usize,
|
|
}
|
|
|
|
impl Search {
|
|
pub fn new(limit: usize) -> Self {
|
|
Self { limit }
|
|
}
|
|
}
|
|
|
|
pub struct SearchNext {
|
|
limit: usize,
|
|
}
|
|
|
|
impl SearchNext {
|
|
pub fn new(limit: usize) -> Self {
|
|
Self { limit }
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Command for Grab {
|
|
async fn execute(&mut self, msg: Context<'_>) -> anyhow::Result<String> {
|
|
let content = if let Some(c) = msg.content {
|
|
c
|
|
} else {
|
|
return Ok("Invalid usage.".into());
|
|
};
|
|
let mut split = content.splitn(2, ' ');
|
|
let split = (split.next().unwrap(), split.next());
|
|
let (author, count) = if let Some(author) = split.1 {
|
|
(author, split.0.parse::<usize>()?)
|
|
} else {
|
|
(split.0, 1)
|
|
};
|
|
if count == 0 {
|
|
return Ok("So are you going to grab anything?".into());
|
|
}
|
|
if author == msg.author {
|
|
return Ok("You can't grab yourself.".into());
|
|
}
|
|
let messages = msg.history.last_msgs(author, count).await;
|
|
if let Some(messages) = messages {
|
|
let message = messages.join(" | ");
|
|
msg.db
|
|
.add_quote(Quote {
|
|
author: author.into(),
|
|
quote: message,
|
|
})
|
|
.await?;
|
|
Ok(format!("Quote added ({} messages).", messages.len()))
|
|
} else {
|
|
Ok("No previous messages to grab.".into())
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Command for Quot {
|
|
async fn execute(&mut self, msg: Context<'_>) -> anyhow::Result<String> {
|
|
let author = msg.content.map(ToString::to_string);
|
|
if let Some(q) = msg.db.get_quote(author).await? {
|
|
Ok(format!("\"{}\" ~{}", q.quote, q.author))
|
|
} else {
|
|
Ok("No quotes found from this user.".into())
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Command for Search {
|
|
async fn execute(&mut self, msg: Context<'_>) -> anyhow::Result<String> {
|
|
let query = if let Some(c) = msg.content {
|
|
c
|
|
} else {
|
|
return Ok("Invalid usage.".into());
|
|
};
|
|
let results = msg
|
|
.db
|
|
.search_quotes(msg.author.into(), query.into(), self.limit)
|
|
.await?;
|
|
if results.is_empty() {
|
|
return Ok("No results.".into());
|
|
}
|
|
let mut buf = String::new();
|
|
for q in &results {
|
|
write!(buf, "\"{}\" ~{}\r\n", q.quote, q.author)?;
|
|
}
|
|
if results.len() == self.limit {
|
|
buf.push_str("Use 'qnext' for more results.");
|
|
}
|
|
Ok(buf)
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Command for SearchNext {
|
|
async fn execute(&mut self, msg: Context<'_>) -> anyhow::Result<String> {
|
|
let results = if let Some(o) = msg.db.advance_search(msg.author.into(), self.limit).await? {
|
|
o
|
|
} else {
|
|
return Ok("You need to initiate a search first using 'qsearch'.".into());
|
|
};
|
|
if results.is_empty() {
|
|
return Ok("No results.".into());
|
|
}
|
|
let mut buf = String::new();
|
|
for q in &results {
|
|
write!(buf, "\"{}\" ~{}\r\n", q.quote, q.author)?;
|
|
}
|
|
if results.len() == self.limit {
|
|
buf.push_str("Use 'qnext' again for more results.");
|
|
}
|
|
Ok(buf)
|
|
}
|
|
}
|