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", "libc",
"num-integer", "num-integer",
"num-traits", "num-traits",
"serde",
"time 0.1.44", "time 0.1.44",
"winapi", "winapi",
] ]
@ -203,6 +204,7 @@ dependencies = [
"dotenv", "dotenv",
"mongodb", "mongodb",
"nougat", "nougat",
"poise",
"serde", "serde",
"serde_json", "serde_json",
"serenity", "serenity",
@ -239,14 +241,38 @@ dependencies = [
"typenum", "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]] [[package]]
name = "darling" name = "darling"
version = "0.13.4" version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
dependencies = [ dependencies = [
"darling_core", "darling_core 0.13.4",
"darling_macro", "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]] [[package]]
@ -263,13 +289,24 @@ dependencies = [
"syn", "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]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.13.4" version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
dependencies = [ dependencies = [
"darling_core", "darling_core 0.13.4",
"quote", "quote",
"syn", "syn",
] ]
@ -1038,6 +1075,36 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 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]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.16" version = "0.2.16"
@ -1368,7 +1435,7 @@ version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
dependencies = [ dependencies = [
"darling", "darling 0.13.4",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -1386,6 +1453,7 @@ dependencies = [
"bitflags", "bitflags",
"bytes", "bytes",
"cfg-if", "cfg-if",
"chrono",
"dashmap", "dashmap",
"flate2", "flate2",
"futures", "futures",

View file

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

View file

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

View file

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