migrate prison commands to poise

This commit is contained in:
nora 2022-06-19 17:55:17 +02:00
parent d6e6ab9699
commit 31255d4a52
4 changed files with 192 additions and 88 deletions

76
Cargo.lock generated
View file

@ -164,6 +164,7 @@ dependencies = [
"libc",
"num-integer",
"num-traits",
"serde",
"time 0.1.44",
"winapi",
]
@ -203,6 +204,7 @@ dependencies = [
"dotenv",
"mongodb",
"nougat",
"poise",
"serde",
"serde_json",
"serenity",
@ -239,14 +241,38 @@ dependencies = [
"typenum",
]
[[package]]
name = "darling"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
dependencies = [
"darling_core 0.12.4",
"darling_macro 0.12.4",
]
[[package]]
name = "darling"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
dependencies = [
"darling_core",
"darling_macro",
"darling_core 0.13.4",
"darling_macro 0.13.4",
]
[[package]]
name = "darling_core"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
@ -263,13 +289,24 @@ dependencies = [
"syn",
]
[[package]]
name = "darling_macro"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
dependencies = [
"darling_core 0.12.4",
"quote",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
dependencies = [
"darling_core",
"darling_core 0.13.4",
"quote",
"syn",
]
@ -1038,6 +1075,36 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "poise"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8af8ef2efaa133d674482f40665db3424cb2c5660a2707918c869603c843b7ad"
dependencies = [
"async-trait",
"derivative",
"futures-core",
"futures-util",
"log",
"once_cell",
"poise_macros",
"regex",
"serenity",
"tokio",
]
[[package]]
name = "poise_macros"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94d99712c7e3cef666f344ccf5c5c729939331096d16c35eba3275028191a1af"
dependencies = [
"darling 0.12.4",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "ppv-lite86"
version = "0.2.16"
@ -1368,7 +1435,7 @@ version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
dependencies = [
"darling",
"darling 0.13.4",
"proc-macro2",
"quote",
"syn",
@ -1386,6 +1453,7 @@ dependencies = [
"bitflags",
"bytes",
"cfg-if",
"chrono",
"dashmap",
"flate2",
"futures",

View file

@ -15,6 +15,7 @@ tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
serde = { version = "1.0.137", features = ["derive"] }
nougat = "0.1.0"
serde_json = "1.0.81"
poise = "0.2.2"
[dependencies.serenity]
version = "0.11.2"

View file

@ -1,3 +1,5 @@
use std::fmt::{Debug, Formatter};
use color_eyre::eyre::{eyre, ContextCompat};
use mongodb::bson::Uuid;
use serenity::{
@ -14,7 +16,7 @@ use tracing::{debug, error, info};
use crate::{
lawsuit::{Lawsuit, LawsuitCtx},
model::SnowflakeId,
Mongo, WrapErr,
Mongo, Report, WrapErr,
};
fn slash_commands(commands: &mut CreateApplicationCommands) -> &mut CreateApplicationCommands {
@ -156,6 +158,12 @@ pub struct Handler {
pub mongo: Mongo,
}
impl Debug for Handler {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("HandlerData")
}
}
pub enum Response {
EphemeralStr(&'static str),
Ephemeral(String),
@ -212,7 +220,6 @@ impl Handler {
let response = match command.data.name.as_str() {
"lawsuit" => lawsuit_command_handler(&command, &ctx, &self.mongo).await,
"prison" => prison_command_handler(&command, &ctx, &self.mongo).await,
_ => Ok(Response::EphemeralStr("not implemented :(")),
};
@ -451,105 +458,131 @@ async fn lawsuit_command_handler(
}
}
async fn prison_command_handler(
command: &ApplicationCommandInteraction,
ctx: &Context,
mongo_client: &Mongo,
) -> color_eyre::Result<Response> {
let options = &command.data.options;
let subcommand = options.get(0).wrap_err("needs subcommand")?;
#[poise::command(
slash_command,
subcommands("prison_set_role", "prison_arrest", "prison_release")
)]
async fn prison(_: crate::Context<'_>) -> color_eyre::Result<()> {
unreachable!()
}
let options = &subcommand.options;
let guild_id = command.guild_id.wrap_err("guild_id not found")?;
/// Die Rolle für Gefangene setzen
#[poise::command(
slash_command,
required_permissions = "MANAGE_GUILD",
on_error = "error_handler"
)]
async fn prison_set_role(
ctx: crate::Context<'_>,
#[description = "Die rolle"] role: Role,
) -> color_eyre::Result<()> {
prison_set_role_impl(ctx, role)
.await
.wrap_err("prison_set_role")
}
let member = command
.member
.as_ref()
.wrap_err("command must be used my member")?;
let permissions = member.permissions.wrap_err("must be in interaction")?;
async fn prison_set_role_impl(ctx: crate::Context<'_>, role: Role) -> color_eyre::Result<()> {
ctx.data()
.mongo
.set_prison_role(
ctx.guild_id().wrap_err("guild_id not found")?.into(),
role.id.into(),
)
.await?;
match subcommand.name.as_str() {
"set_role" => {
if !permissions.contains(Permissions::MANAGE_GUILD) {
return Ok(Response::NoPermissions);
}
ctx.say("isch gsetzt").await.wrap_err("reply")?;
let role = RoleOption::get(options.get(0))?;
Ok(())
}
mongo_client
.set_prison_role(guild_id.into(), role.id.into())
.await?;
/// Jemanden einsperren
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")]
async fn prison_arrest(
ctx: crate::Context<'_>,
#[description = "Die Person zum einsperren"] user: User,
) -> color_eyre::Result<()> {
prison_arrest_impl(ctx, user)
.await
.wrap_err("prison_arrest")
}
Ok(Response::EphemeralStr("isch gsetzt"))
async fn prison_arrest_impl(ctx: crate::Context<'_>, user: User) -> color_eyre::Result<()> {
let mongo_client = &ctx.data().mongo;
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
let http = &ctx.discord().http;
let state = mongo_client.find_or_insert_state(guild_id.into()).await?;
let role = state.prison_role;
let role = match role {
Some(role) => role,
None => {
ctx.say("du mosch zerst e rolle setze mit /prison set_role");
return Ok(());
}
"arrest" => {
if !permissions.contains(Permissions::MANAGE_GUILD) {
return Ok(Response::NoPermissions);
}
};
let (user, _) = UserOption::get(options.get(0))?;
mongo_client
.add_to_prison(guild_id.into(), user.id.into())
.await?;
let state = mongo_client.find_or_insert_state(guild_id.into()).await?;
let role = state.prison_role;
guild_id
.member(http, user.id)
.await
.wrap_err("fetching guild member")?
.add_role(http, role)
.await
.wrap_err("add guild member role")?;
Ok(())
}
let role = match role {
Some(role) => role,
None => {
return Ok(Response::EphemeralStr(
"du mosch zerst e rolle setze mit /prison set_role",
))
}
};
/// Einen Gefangenen freilassen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")]
async fn prison_release(
ctx: crate::Context<'_>,
#[description = "Die Person zum freilassen"] user: User,
) -> color_eyre::Result<()> {
prison_release_impl(ctx, user)
.await
.wrap_err("prison_release")
}
mongo_client
.add_to_prison(guild_id.into(), user.id.into())
async fn prison_release_impl(ctx: crate::Context<'_>, user: User) -> color_eyre::Result<()> {
let mongo_client = &ctx.data().mongo;
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
let http = &ctx.discord().http;
let state = mongo_client.find_or_insert_state(guild_id.into()).await?;
let role = state.prison_role;
let role = match role {
Some(role) => role,
None => {
ctx.say("du mosch zerst e rolle setze mit /prison set_role")
.await?;
guild_id
.member(&ctx.http, user.id)
.await
.wrap_err("fetching guild member")?
.add_role(&ctx.http, role)
.await
.wrap_err("add guild member role")?;
Ok(Response::EphemeralStr("hani igsperrt"))
return Ok(());
}
"release" => {
if !permissions.contains(Permissions::MANAGE_GUILD) {
return Ok(Response::NoPermissions);
}
};
let (user, _) = UserOption::get(options.get(0))?;
mongo_client
.remove_from_prison(guild_id.into(), user.id.into())
.await?;
let state = mongo_client.find_or_insert_state(guild_id.into()).await?;
let role = state.prison_role;
guild_id
.member(http, user.id)
.await
.wrap_err("fetching guild member")?
.remove_role(http, role)
.await
.wrap_err("remove guild member role")?;
let role = match role {
Some(role) => role,
None => {
return Ok(Response::EphemeralStr(
"du mosch zerst e rolle setze mit /prison set_role",
))
}
};
ctx.say("d'freiheit wartet").await?;
mongo_client
.remove_from_prison(guild_id.into(), user.id.into())
.await?;
Ok(())
}
guild_id
.member(&ctx.http, user.id)
.await
.wrap_err("fetching guild member")?
.remove_role(&ctx.http, role)
.await
.wrap_err("remove guild member role")?;
Ok(Response::EphemeralStr("d'freiheit wartet"))
}
_ => Err(eyre!("Unknown subcommand")),
}
async fn error_handler(error: poise::FrameworkError<'_, Handler, Report>) {
error!(?error, "Error during command execution");
}
#[nougat::gat]

View file

@ -6,13 +6,15 @@ mod model;
use std::env;
use color_eyre::{eyre::WrapErr, Result};
use color_eyre::{eyre::WrapErr, Report, Result};
use serenity::{model::prelude::*, prelude::*};
use tracing::info;
use tracing_subscriber::EnvFilter;
use crate::{handler::Handler, model::Mongo};
type Context<'a> = poise::Context<'a, Handler, Report>;
#[tokio::main]
async fn main() -> Result<()> {
color_eyre::install()?;