use crate::{Context, Error, models::{FilterAction, MessageFilter}};
use poise::{serenity_prelude as serenity, AutocompleteChoice};
use std::str::FromStr;
use futures::{Stream, StreamExt};
/// Base command for all filter actions
///
/// Provides a CRUD interface for managing automatic message filters
#[poise::command(slash_command, prefix_command)]
pub async fn filter(ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
/// Lists message filters
///
/// Usage:
/// filter list
#[poise::command(slash_command, ephemeral, prefix_command)]
pub async fn list(ctx: Context<'_>) -> Result<(), Error> {
let pool = ctx.data().pg.lock().unwrap().clone();
let filters = sqlx::query_as::<_, MessageFilter>("SELECT * FROM message_filter WHERE guild_id=$1").bind(ctx.guild().unwrap().id.0.to_string())
.fetch_all(&pool).await?;
let mut list = String::from("");
if filters.len() == 0 {
list = "No filters set, try adding one with `/filter add`!".to_string();
} else {
for f in filters {
list.push_str(&format!("{}\n", f.to_string()));
}
}
ctx.send(|m| {
m.embed(|e| {
e.title("Message Filter List");
e.description(list);
e
})
}).await?;
Ok(())
}
/// Creates a new message filter
///
/// Usage:
/// filter add <pattern> <action>
///
/// Where <action> is one of "review" or "delete"
#[poise::command(slash_command, ephemeral, prefix_command)]
pub async fn add(ctx: Context<'_>,
#[description = "The regular expression to match against"]
regex: String,
#[description = "The action to take when the expression is matched"]
#[autocomplete = "ac_action"]
action: String,
) -> Result<(), Error> {
let pool = ctx.data().pg.lock().unwrap().clone();
let action = FilterAction::from_str(&action)?;
sqlx::query("INSERT INTO message_filter (pattern, action, guild_id) VALUES ($1, $2, $3)")
.bind(regex)
.bind(action as FilterAction)
.bind(ctx.guild().unwrap().id.0.to_string())
.execute(&pool)
.await?;
ctx.say("Sounds good! I've written that down and will keep a close eye out").await?;
Ok(())
}
async fn ac_action(_ctx: Context<'_>, partial: String) -> impl Stream<Item = String> {
futures::stream::iter(&["review", "delete"])
.filter(move |name| futures::future::ready(name.starts_with(&partial)))
.map(|name| name.to_string())
}