From 323611568d279eb0481216902027ca70d585026c Mon Sep 17 00:00:00 2001 From: Ushie Date: Sat, 15 Apr 2023 23:41:14 +0300 Subject: [PATCH] feat: use `go-parse-duration` for time parameters --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/commands/moderation.rs | 40 +++++++++++--------------------------- src/utils/moderation.rs | 14 +++++++++---- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b38e730..13eceda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,6 +588,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "go-parse-duration" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558b88954871f5e5b2af0e62e2e176c8bde7a6c2c4ed41b13d138d96da2e2cbd" + [[package]] name = "h2" version = "0.3.16" @@ -1297,6 +1303,7 @@ dependencies = [ "decancer", "dirs", "dotenv", + "go-parse-duration", "hmac-sha256", "mongodb", "poise", diff --git a/Cargo.toml b/Cargo.toml index dfad295..b6a060b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,4 @@ tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_leve tracing-subscriber = "0.3.16" hmac-sha256 = "1.1.6" base64 = "0.21.0" +go-parse-duration = "0.1.1" diff --git a/src/commands/moderation.rs b/src/commands/moderation.rs index 1f9073d..d0a4916 100644 --- a/src/commands/moderation.rs +++ b/src/commands/moderation.rs @@ -1,5 +1,6 @@ use bson::{doc, Document}; use chrono::{Duration, Utc}; +use crate::utils::moderation::parse_duration; use mongodb::options::{UpdateModifications, UpdateOptions}; use poise::serenity_prelude::{ self as serenity, Mentionable, PermissionOverwrite, Permissions, UserId, @@ -197,16 +198,11 @@ pub async fn unmute( } /// Mute a member. -#[allow(clippy::too_many_arguments)] #[poise::command(slash_command)] pub async fn mute( ctx: Context<'_>, - #[description = "The member to mute"] member: UserId, - #[description = "Seconds"] seconds: Option, - #[description = "Minutes"] minutes: Option, - #[description = "Hours"] hours: Option, - #[description = "Days"] days: Option, - #[description = "Months"] months: Option, + #[description = "The member to mute"] member: User, + #[description = "The duration of the mute"] duration: String, #[description = "The reason of the mute"] reason: String, ) -> Result<(), Error> { let user = to_user!(member, ctx); @@ -214,28 +210,14 @@ pub async fn mute( let now = Utc::now(); let mut mute_duration = Duration::zero(); - if let Some(seconds) = seconds { - mute_duration = mute_duration - .checked_add(&Duration::seconds(seconds)) - .unwrap(); - } - if let Some(minutes) = minutes { - mute_duration = mute_duration - .checked_add(&Duration::minutes(minutes)) - .unwrap(); - } - if let Some(hours) = hours { - mute_duration = mute_duration.checked_add(&Duration::hours(hours)).unwrap(); - } - if let Some(days) = days { - mute_duration = mute_duration.checked_add(&Duration::days(days)).unwrap(); - } - if let Some(months) = months { - const DAYS_IN_MONTH: i64 = 30; - mute_duration = mute_duration - .checked_add(&Duration::days(months * DAYS_IN_MONTH)) - .unwrap(); - } + match parse_duration(duration) { + Ok(duration) => { + mute_duration = duration; + } + Err(err) => { + error!("Failed to parse duration: {:?}", err); + } + } let data = &mut *ctx.data().write().await; let configuration = &data.configuration; diff --git a/src/utils/moderation.rs b/src/utils/moderation.rs index 4bff8f2..1ee79e8 100644 --- a/src/utils/moderation.rs +++ b/src/utils/moderation.rs @@ -1,6 +1,7 @@ use std::cmp; use std::sync::Arc; +use chrono::Duration; use mongodb::options::FindOptions; use poise::serenity_prelude::{ChannelId, GuildChannel, GuildId, Mentionable, User, UserId}; use tokio::task::JoinHandle; @@ -18,10 +19,10 @@ use crate::{Context, Error}; pub enum ModerationKind { Mute(User, User, String, Option, Option), /* User, Command author, Reason, Expires, Error */ Unmute(User, User, Option), // User, Command author, Error - Ban(User, User, Option, Option), // User, Command author, Reason, Error - Unban(User, User, Option), // User, Command author, Error - Lock(GuildChannel, User, Option), // Channel name, Command author, Error - Unlock(GuildChannel, User, Option), // Channel name, Command author, Error + Ban(User, User, Option, Option), // User, Command author, Reason, Error + Unban(User, User, Option), // User, Command author, Error + Lock(GuildChannel, User, Option), // Channel name, Command author, Error + Unlock(GuildChannel, User, Option), // Channel name, Command author, Error } pub enum BanKind { Ban(User, Option, Option), // User, Amount of days to delete messages, Reason @@ -399,3 +400,8 @@ pub async fn mute_moderation( Ok((is_currently_muted, removed_roles)) } + +pub fn parse_duration(duration: String) -> Result { + let d = go_parse_duration::parse_duration(&duration)?; + Ok(Duration::nanoseconds(d)) +}