From f98c768498ed6ee979d65256b8ef67aa6aa62ca3 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 18:46:18 +0700 Subject: [PATCH 01/15] refactor: remove redundant to_string() in get_emoji calls --- src/commands/clear.rs | 4 ++-- src/commands/config.rs | 14 +++++++------- src/commands/filters.rs | 12 ++++++------ src/commands/join.rs | 6 +++--- src/commands/leave.rs | 2 +- src/commands/pause.rs | 4 ++-- src/commands/play.rs | 10 +++++----- src/commands/queue.rs | 2 +- src/commands/remove.rs | 4 ++-- src/commands/resume.rs | 4 ++-- src/commands/seek.rs | 4 ++-- src/commands/skip.rs | 4 ++-- src/commands/stop.rs | 4 ++-- src/commands/volume.rs | 4 ++-- src/utils/emojis.rs | 10 ++-------- 15 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/commands/clear.rs b/src/commands/clear.rs index f39bace..6788fd8 100644 --- a/src/commands/clear.rs +++ b/src/commands/clear.rs @@ -9,9 +9,9 @@ use poise::serenity_prelude as serenity; pub async fn clear(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let playlist_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "album".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; let lava_client = ctx.data().lavalink.clone(); let Some(player) = lava_client.get_player_context(guild_id) else { diff --git a/src/commands/config.rs b/src/commands/config.rs index c2d367f..136d5a1 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -79,7 +79,7 @@ async fn djrole( ) -> Result<(), Error> { let guild_id = ctx.guild_id().ok_or("Must be in a guild")?.get() as i64; let db = ctx.data().database.pool(); - let success_emoji = get_emoji(ctx.serenity_context(), "check".to_string()).await; + let success_emoji = get_emoji(ctx.serenity_context(), "check").await; let role_id = role.clone().map(|r| r.id.get() as i64); queries::update_dj_role(db, guild_id, role_id).await?; @@ -115,7 +115,7 @@ async fn volume( queries::update_volume(db, guild_id, vol).await?; - let volume_emoji = get_emoji(ctx.serenity_context(), "vol3".to_string()).await; + let volume_emoji = get_emoji(ctx.serenity_context(), "vol3").await; let embed = serenity::CreateEmbed::default() .title(format!( "{} Default Volume Updated", @@ -148,7 +148,7 @@ async fn autodisconnect( } else { "Auto disconnect disabled".to_string() }; - let clock_emoji = get_emoji(ctx.serenity_context(), "clock".to_string()).await; + let clock_emoji = get_emoji(ctx.serenity_context(), "clock").await; let embed = serenity::CreateEmbed::default() .title(format!( "{} Auto Disconnect Updated", @@ -186,7 +186,7 @@ async fn announce( "Song announcements disabled".to_string() }; - let song_emoji = get_emoji(ctx.serenity_context(), "song".to_string()).await; + let song_emoji = get_emoji(ctx.serenity_context(), "song").await; let embed = serenity::CreateEmbed::default() .title(format!( "{} Announcements Updated", @@ -213,7 +213,7 @@ async fn maxqueue( queries::update_max_queue_length(db, guild_id, length).await?; - let album_emoji = get_emoji(ctx.serenity_context(), "album".to_string()).await; + let album_emoji = get_emoji(ctx.serenity_context(), "album").await; let embed = serenity::CreateEmbed::default() .title(format!( "{} Max Queue Length Updated", @@ -243,7 +243,7 @@ async fn filters( "Audio filters are now disabled" }; - let filter_emoji = get_emoji(ctx.serenity_context(), "filter".to_string()).await; + let filter_emoji = get_emoji(ctx.serenity_context(), "filter").await; let embed = serenity::CreateEmbed::default() .title(format!( "{} Filters Updated", @@ -263,7 +263,7 @@ async fn reset(ctx: Context<'_>) -> Result<(), Error> { let db = ctx.data().database.pool(); queries::reset_guild_config(db, guild_id).await?; - let recycle_emoji = get_emoji(ctx.serenity_context(), "recycle".to_string()).await; + let recycle_emoji = get_emoji(ctx.serenity_context(), "recycle").await; let embed = serenity::CreateEmbed::default() .title(format!( "{} Configuration Reset", diff --git a/src/commands/filters.rs b/src/commands/filters.rs index c8eb715..0081354 100644 --- a/src/commands/filters.rs +++ b/src/commands/filters.rs @@ -45,7 +45,7 @@ async fn apply( #[autocomplete = "filter_autocomplete"] preset: String, ) -> Result<(), Error> { - let error_emoji = get_emoji(ctx.serenity_context(), "error".to_string()).await; + let error_emoji = get_emoji(ctx.serenity_context(), "error").await; if !permissions::check_dj_or_admin(ctx).await? { let embed = serenity::CreateEmbed::default() @@ -132,7 +132,7 @@ async fn apply( #[poise::command(slash_command)] async fn list(ctx: Context<'_>) -> Result<(), Error> { let mut description = String::new(); - let filter_emoji = get_emoji(ctx.serenity_context(), "filter".to_string()).await; + let filter_emoji = get_emoji(ctx.serenity_context(), "filter").await; for preset in FilterPreset::all_presets() { description.push_str(&format!( @@ -161,8 +161,8 @@ async fn list(ctx: Context<'_>) -> Result<(), Error> { /// Remove all filters #[poise::command(slash_command)] async fn clear(ctx: Context<'_>) -> Result<(), Error> { - let error_emoji = get_emoji(ctx.serenity_context(), "error".to_string()).await; - let check_emoji = get_emoji(ctx.serenity_context(), "check".to_string()).await; + let error_emoji = get_emoji(ctx.serenity_context(), "error").await; + let check_emoji = get_emoji(ctx.serenity_context(), "check").await; if !permissions::check_dj_or_admin(ctx).await? { let embed = serenity::CreateEmbed::default() @@ -207,8 +207,8 @@ async fn custom( #[description = "Bass gain (-0.25 to 1.0)"] bass: Option, #[description = "Treble gain (-0.25 to 1.0)"] treble: Option, ) -> Result<(), Error> { - let error_emoji = get_emoji(ctx.serenity_context(), "error".to_string()).await; - let check_emoji = get_emoji(ctx.serenity_context(), "check".to_string()).await; + let error_emoji = get_emoji(ctx.serenity_context(), "error").await; + let check_emoji = get_emoji(ctx.serenity_context(), "check").await; if !permissions::check_dj_or_admin(ctx).await? { let embed = serenity::CreateEmbed::default() diff --git a/src/commands/join.rs b/src/commands/join.rs index 299ff54..d44f3f8 100644 --- a/src/commands/join.rs +++ b/src/commands/join.rs @@ -23,11 +23,11 @@ pub async fn join(ctx: Context<'_>) -> Result<(), Error> { .and_then(|vs| vs.channel_id) }); let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; let alert_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "caution".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "caution").await; if user_voice.is_none() { let embed = serenity::CreateEmbed::default() .title(format!("{} Cannot Join", error_emoji.unwrap_or_default())) diff --git a/src/commands/leave.rs b/src/commands/leave.rs index f5a0e1b..8276dd8 100644 --- a/src/commands/leave.rs +++ b/src/commands/leave.rs @@ -11,7 +11,7 @@ pub async fn leave(ctx: Context<'_>) -> Result<(), Error> { let manager = songbird::get(ctx.serenity_context()).await.unwrap().clone(); let lava_client = ctx.data().lavalink.clone(); - let success_emoji = emojis::get_emoji(ctx.serenity_context(), "check".to_string()).await; + let success_emoji = emojis::get_emoji(ctx.serenity_context(), "check").await; lava_client.delete_player(guild_id).await?; if manager.get(guild_id).is_some() { diff --git a/src/commands/pause.rs b/src/commands/pause.rs index 0439f82..d04f856 100644 --- a/src/commands/pause.rs +++ b/src/commands/pause.rs @@ -14,9 +14,9 @@ pub async fn pause(ctx: Context<'_>) -> Result<(), Error> { let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; let lava_client = ctx.data().lavalink.clone(); if !is_dj_or_admin { diff --git a/src/commands/play.rs b/src/commands/play.rs index b1b66b0..95376be 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -79,15 +79,15 @@ pub async fn play( let has_joined = _join(&ctx, guild_id, None).await?; let lava_client = ctx.data().lavalink.clone(); let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let _success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; let playlist_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "album".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; let player_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "player".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "player").await; let spotify_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "spotify".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "spotify").await; let pool = ctx.data().database.pool(); let guild_config = queries::get_guild_config(pool, guild_id.get() as i64).await?; let max_queue = guild_config.max_queue_length; diff --git a/src/commands/queue.rs b/src/commands/queue.rs index c57aba4..96ce6ee 100644 --- a/src/commands/queue.rs +++ b/src/commands/queue.rs @@ -10,7 +10,7 @@ pub async fn queue(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); let lava_client = ctx.data().lavalink.clone(); let album_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "album".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; let player = match lava_client.get_player_context(guild_id) { Some(p) => p, None => { diff --git a/src/commands/remove.rs b/src/commands/remove.rs index 0844e76..4dec1c1 100644 --- a/src/commands/remove.rs +++ b/src/commands/remove.rs @@ -20,9 +20,9 @@ pub async fn remove( let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; if !is_dj_or_admin { let embed = serenity::CreateEmbed::default() .title(format!( diff --git a/src/commands/resume.rs b/src/commands/resume.rs index 35ff280..2f4abc7 100644 --- a/src/commands/resume.rs +++ b/src/commands/resume.rs @@ -14,9 +14,9 @@ pub async fn resume(ctx: Context<'_>) -> Result<(), Error> { let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; let lava_client = ctx.data().lavalink.clone(); if !is_dj_or_admin { diff --git a/src/commands/seek.rs b/src/commands/seek.rs index 8702c83..1c7082a 100644 --- a/src/commands/seek.rs +++ b/src/commands/seek.rs @@ -16,8 +16,8 @@ pub async fn seek( let lava_client = ctx.data().lavalink.clone(); let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; - let clock_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "clock".to_string()); + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let clock_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "clock"); let Some(player) = lava_client.get_player_context(guild_id) else { let embed = serenity::CreateEmbed::default() .title(format!("{} Not Connected", error_emoji.unwrap_or_default())) diff --git a/src/commands/skip.rs b/src/commands/skip.rs index c667968..78a7157 100644 --- a/src/commands/skip.rs +++ b/src/commands/skip.rs @@ -16,9 +16,9 @@ pub async fn skip(ctx: Context<'_>) -> Result<(), Error> { let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let skip_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "skiparrow".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "skiparrow").await; if !is_dj_or_admin { let embed = serenity::CreateEmbed::default() .title(format!( diff --git a/src/commands/stop.rs b/src/commands/stop.rs index 71d4703..e022fac 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -11,8 +11,8 @@ use poise::serenity_prelude as serenity; #[poise::command(slash_command, prefix_command)] pub async fn stop(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); - let error_emoji = get_emoji(ctx.serenity_context(), "error".to_string()).await; - let stop_emoji = get_emoji(ctx.serenity_context(), "disc".to_string()).await; + let error_emoji = get_emoji(ctx.serenity_context(), "error").await; + let stop_emoji = get_emoji(ctx.serenity_context(), "disc").await; let lava_client = ctx.data().lavalink.clone(); diff --git a/src/commands/volume.rs b/src/commands/volume.rs index a5d2596..afe17d2 100644 --- a/src/commands/volume.rs +++ b/src/commands/volume.rs @@ -16,9 +16,9 @@ pub async fn volume( let guild_id = ctx.guild_id().unwrap(); let lava_client = ctx.data().lavalink.clone(); let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let vol_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "vol3".to_string()).await; + crate::utils::emojis::get_emoji(ctx.serenity_context(), "vol3").await; let Some(player) = lava_client.get_player_context(guild_id) else { let embed = serenity::CreateEmbed::default() .title(format!("{} Not Connected", error_emoji.unwrap_or_default())) diff --git a/src/utils/emojis.rs b/src/utils/emojis.rs index 400edba..c3f0673 100644 --- a/src/utils/emojis.rs +++ b/src/utils/emojis.rs @@ -1,11 +1,5 @@ use poise::serenity_prelude as serenity; -pub async fn get_emoji(context: &serenity::Context, name: String) -> Option { - let emojis = context.http.get_application_emojis().await.unwrap(); - for emoji in emojis { - if emoji.name == name { - return Some(emoji.to_string()); - } - } - None +pub async fn get_emoji(context: &serenity::Context, name: &str) -> Option { + context.http.get_application_emojis().await.ok().and_then(|emojis| emojis.find(|emoji| emoji.name == name).map(String::from)) } From ef707238a915ac6d3495499dea88e86b3e89bf6d Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 18:53:28 +0700 Subject: [PATCH 02/15] refactor: remove redundant Arc wrapping when Pool is already an Arc --- src/utils/autodisconnect.rs | 5 ++--- src/utils/voicechannel.rs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/utils/autodisconnect.rs b/src/utils/autodisconnect.rs index a0c05ea..2a41e8f 100644 --- a/src/utils/autodisconnect.rs +++ b/src/utils/autodisconnect.rs @@ -1,5 +1,4 @@ use poise::serenity_prelude as serenity; -use std::sync::Arc; use std::time::Duration; use tokio::time::sleep; @@ -7,14 +6,14 @@ use crate::database::queries; pub struct AutoDisconnectManager { guild_id: serenity::GuildId, - db: Arc, + db: sqlx::SqlitePool, ctx: serenity::Context, } impl AutoDisconnectManager { pub fn new( guild_id: serenity::GuildId, - db: Arc, + db: sqlx::SqlitePool, ctx: serenity::Context, ) -> Self { Self { guild_id, db, ctx } diff --git a/src/utils/voicechannel.rs b/src/utils/voicechannel.rs index af8b1b4..7067d3a 100644 --- a/src/utils/voicechannel.rs +++ b/src/utils/voicechannel.rs @@ -59,7 +59,7 @@ pub async fn _join( // Start auto-disconnect monitoring let auto_disconnect = AutoDisconnectManager::new( guild_id, - Arc::new(db.clone()), + db.clone(), ctx.serenity_context().clone(), ); auto_disconnect.start_monitoring(lava_client.clone()).await; From 7eb1c3d520543c5a661650f78e357529eb711ee0 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 18:54:30 +0700 Subject: [PATCH 03/15] refactor: remove another redundant Arc when Pool is already an Arc --- src/utils/player_data.rs | 4 ++-- src/utils/voicechannel.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/player_data.rs b/src/utils/player_data.rs index 8da296b..cd69b4b 100644 --- a/src/utils/player_data.rs +++ b/src/utils/player_data.rs @@ -5,14 +5,14 @@ use std::sync::Arc; pub struct PlayerData { pub channel_id: serenity::ChannelId, pub http: Arc, - pub db: Arc, + pub db: sqlx::SqlitePool, } impl PlayerData { pub fn new( channel_id: serenity::ChannelId, http: Arc, - db: Arc, + db: sqlx::SqlitePool, ) -> Self { Self { channel_id, diff --git a/src/utils/voicechannel.rs b/src/utils/voicechannel.rs index 7067d3a..872eaac 100644 --- a/src/utils/voicechannel.rs +++ b/src/utils/voicechannel.rs @@ -42,7 +42,7 @@ pub async fn _join( let player_data = PlayerData::new( ctx.channel_id(), ctx.serenity_context().http.clone(), - Arc::new(ctx.data().database.pool().clone()), + ctx.data().database.pool().clone(), ); let player_ctx = lava_client From a0ba193aae314f6213554d1180e6c99c78ebbe14 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:22:15 +0700 Subject: [PATCH 04/15] fix: several minor bug-fixes --- src/commands/config.rs | 4 ++-- src/music_events.rs | 4 ++-- src/utils/emojis.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/config.rs b/src/commands/config.rs index 136d5a1..96ce4a8 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -80,7 +80,7 @@ async fn djrole( let guild_id = ctx.guild_id().ok_or("Must be in a guild")?.get() as i64; let db = ctx.data().database.pool(); let success_emoji = get_emoji(ctx.serenity_context(), "check").await; - let role_id = role.clone().map(|r| r.id.get() as i64); + let role_id = role.as_ref().map(|r| r.id.get() as i64); queries::update_dj_role(db, guild_id, role_id).await?; let description = if let Some(r) = role { @@ -173,7 +173,7 @@ async fn announce( let guild_id = ctx.guild_id().ok_or("Must be in a guild")?.get() as i64; let db = ctx.data().database.pool(); - let channel_id = channel.clone().map(|c| c.id.get() as i64); + let channel_id = channel.as_ref().map(|c| c.id.get() as i64); queries::update_announce_settings(db, guild_id, enabled, channel_id).await?; let description = if enabled { diff --git a/src/music_events.rs b/src/music_events.rs index 323b5e3..e7cf330 100644 --- a/src/music_events.rs +++ b/src/music_events.rs @@ -30,7 +30,7 @@ pub async fn track_start(client: LavalinkClient, _session_id: String, event: &ev if let Some(player) = client.get_player_context(event.guild_id) { if let Ok(data) = player.data::() { let config = match crate::database::queries::get_guild_config( - data.db.as_ref(), + &data.db, event.guild_id.0 as i64, ) .await @@ -87,7 +87,7 @@ pub async fn track_end(client: LavalinkClient, _session_id: String, event: &even if let Some(player) = client.get_player_context(event.guild_id) { if let Ok(data) = player.data::() { let config = match crate::database::queries::get_guild_config( - data.db.as_ref(), + &data.db, event.guild_id.0 as i64, ) .await diff --git a/src/utils/emojis.rs b/src/utils/emojis.rs index c3f0673..5190253 100644 --- a/src/utils/emojis.rs +++ b/src/utils/emojis.rs @@ -1,5 +1,5 @@ use poise::serenity_prelude as serenity; pub async fn get_emoji(context: &serenity::Context, name: &str) -> Option { - context.http.get_application_emojis().await.ok().and_then(|emojis| emojis.find(|emoji| emoji.name == name).map(String::from)) + context.http.get_application_emojis().await.ok().and_then(|emojis| emojis.into_iter().map(|emoji| emoji.name).find(|name| name.as_str() == name)) } From f78ebd7b70f38318ad50a6ccf572191e7fd32000 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:24:41 +0700 Subject: [PATCH 05/15] [style,refactor]: format and collapse several if-statements --- src/commands/clear.rs | 6 +- src/commands/join.rs | 9 +-- src/commands/pause.rs | 6 +- src/commands/play.rs | 24 +++--- src/commands/queue.rs | 3 +- src/commands/remove.rs | 6 +- src/commands/resume.rs | 6 +- src/commands/seek.rs | 3 +- src/commands/skip.rs | 6 +- src/commands/volume.rs | 6 +- src/music_events.rs | 156 +++++++++++++++++------------------- src/utils/autodisconnect.rs | 6 +- src/utils/emojis.rs | 12 ++- 13 files changed, 114 insertions(+), 135 deletions(-) diff --git a/src/commands/clear.rs b/src/commands/clear.rs index 6788fd8..7ea005c 100644 --- a/src/commands/clear.rs +++ b/src/commands/clear.rs @@ -8,10 +8,8 @@ use poise::serenity_prelude as serenity; #[poise::command(slash_command, prefix_command)] pub async fn clear(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let playlist_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let playlist_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; let lava_client = ctx.data().lavalink.clone(); let Some(player) = lava_client.get_player_context(guild_id) else { diff --git a/src/commands/join.rs b/src/commands/join.rs index d44f3f8..c160763 100644 --- a/src/commands/join.rs +++ b/src/commands/join.rs @@ -22,12 +22,9 @@ pub async fn join(ctx: Context<'_>) -> Result<(), Error> { .get(&cache.current_user().id) .and_then(|vs| vs.channel_id) }); - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; - let alert_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "caution").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let success_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; + let alert_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "caution").await; if user_voice.is_none() { let embed = serenity::CreateEmbed::default() .title(format!("{} Cannot Join", error_emoji.unwrap_or_default())) diff --git a/src/commands/pause.rs b/src/commands/pause.rs index d04f856..f350d58 100644 --- a/src/commands/pause.rs +++ b/src/commands/pause.rs @@ -13,10 +13,8 @@ pub async fn pause(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let success_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; let lava_client = ctx.data().lavalink.clone(); if !is_dj_or_admin { diff --git a/src/commands/play.rs b/src/commands/play.rs index 95376be..f99bb1b 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -78,16 +78,11 @@ pub async fn play( let guild_id = ctx.guild_id().unwrap(); let has_joined = _join(&ctx, guild_id, None).await?; let lava_client = ctx.data().lavalink.clone(); - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let _success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; - let playlist_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; - let player_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "player").await; - let spotify_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "spotify").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let _success_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; + let playlist_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; + let player_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "player").await; + let spotify_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "spotify").await; let pool = ctx.data().database.pool(); let guild_config = queries::get_guild_config(pool, guild_id.get() as i64).await?; let max_queue = guild_config.max_queue_length; @@ -206,10 +201,11 @@ pub async fn play( return Ok(()); } - if let Ok(player_data) = player.get_player().await { - if player_data.track.is_none() && queue.get_track(0).await.is_ok_and(|x| x.is_some()) { - player.skip()?; - } + if let Ok(player_data) = player.get_player().await + && player_data.track.is_none() + && queue.get_track(0).await.is_ok_and(|x| x.is_some()) + { + player.skip()?; } Ok(()) diff --git a/src/commands/queue.rs b/src/commands/queue.rs index 96ce6ee..d61a410 100644 --- a/src/commands/queue.rs +++ b/src/commands/queue.rs @@ -9,8 +9,7 @@ use poise::serenity_prelude as serenity; pub async fn queue(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); let lava_client = ctx.data().lavalink.clone(); - let album_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; + let album_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "album").await; let player = match lava_client.get_player_context(guild_id) { Some(p) => p, None => { diff --git a/src/commands/remove.rs b/src/commands/remove.rs index 4dec1c1..9adad38 100644 --- a/src/commands/remove.rs +++ b/src/commands/remove.rs @@ -19,10 +19,8 @@ pub async fn remove( let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let success_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; if !is_dj_or_admin { let embed = serenity::CreateEmbed::default() .title(format!( diff --git a/src/commands/resume.rs b/src/commands/resume.rs index 2f4abc7..2e3b98a 100644 --- a/src/commands/resume.rs +++ b/src/commands/resume.rs @@ -13,10 +13,8 @@ pub async fn resume(ctx: Context<'_>) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let success_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let success_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "check").await; let lava_client = ctx.data().lavalink.clone(); if !is_dj_or_admin { diff --git a/src/commands/seek.rs b/src/commands/seek.rs index 1c7082a..1329af8 100644 --- a/src/commands/seek.rs +++ b/src/commands/seek.rs @@ -15,8 +15,7 @@ pub async fn seek( let guild_id = ctx.guild_id().unwrap(); let lava_client = ctx.data().lavalink.clone(); - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; let clock_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "clock"); let Some(player) = lava_client.get_player_context(guild_id) else { let embed = serenity::CreateEmbed::default() diff --git a/src/commands/skip.rs b/src/commands/skip.rs index 78a7157..ab3ead8 100644 --- a/src/commands/skip.rs +++ b/src/commands/skip.rs @@ -15,10 +15,8 @@ pub async fn skip(ctx: Context<'_>) -> Result<(), Error> { let author_name = ctx.author().name.clone(); let is_dj_or_admin = permissions::check_dj_or_admin(ctx).await?; let check_in_voice = permissions::check_in_voice(ctx).await?; - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let skip_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "skiparrow").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let skip_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "skiparrow").await; if !is_dj_or_admin { let embed = serenity::CreateEmbed::default() .title(format!( diff --git a/src/commands/volume.rs b/src/commands/volume.rs index afe17d2..6c3a147 100644 --- a/src/commands/volume.rs +++ b/src/commands/volume.rs @@ -15,10 +15,8 @@ pub async fn volume( ) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap(); let lava_client = ctx.data().lavalink.clone(); - let error_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; - let vol_emoji = - crate::utils::emojis::get_emoji(ctx.serenity_context(), "vol3").await; + let error_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "cross").await; + let vol_emoji = crate::utils::emojis::get_emoji(ctx.serenity_context(), "vol3").await; let Some(player) = lava_client.get_player_context(guild_id) else { let embed = serenity::CreateEmbed::default() .title(format!("{} Not Connected", error_emoji.unwrap_or_default())) diff --git a/src/music_events.rs b/src/music_events.rs index e7cf330..c02063c 100644 --- a/src/music_events.rs +++ b/src/music_events.rs @@ -27,13 +27,12 @@ pub async fn ready_event(client: LavalinkClient, session_id: String, event: &eve pub async fn track_start(client: LavalinkClient, _session_id: String, event: &events::TrackStart) { info!("Track started: {:?}", event.track.info.title); - if let Some(player) = client.get_player_context(event.guild_id) { - if let Ok(data) = player.data::() { - let config = match crate::database::queries::get_guild_config( - &data.db, - event.guild_id.0 as i64, - ) - .await + if let Some(player) = client.get_player_context(event.guild_id) + && let Ok(data) = player.data::() + { + let config = + match crate::database::queries::get_guild_config(&data.db, event.guild_id.0 as i64) + .await { Ok(c) => c, Err(e) => { @@ -42,34 +41,33 @@ pub async fn track_start(client: LavalinkClient, _session_id: String, event: &ev } }; - if !config.announce_songs { - return; - } - - let announce_channel = if let Some(channel_id) = config.announce_channel_id { - serenity::ChannelId::new(channel_id as u64) - } else { - data.channel_id - }; - - let requester_id = event - .track - .user_data - .as_ref() - .and_then(|d| d["requester_id"].as_u64()) - .unwrap_or(0); - - let embed = AnnouncementBuilder::now_playing(&event.track, requester_id); + if !config.announce_songs { + return; + } - if let Err(e) = announce_channel - .send_message( - data.http.as_ref(), - serenity::CreateMessage::default().embed(embed), - ) - .await - { - error!("Failed to send track start announcement: {:?}", e); - } + let announce_channel = if let Some(channel_id) = config.announce_channel_id { + serenity::ChannelId::new(channel_id as u64) + } else { + data.channel_id + }; + + let requester_id = event + .track + .user_data + .as_ref() + .and_then(|d| d["requester_id"].as_u64()) + .unwrap_or(0); + + let embed = AnnouncementBuilder::now_playing(&event.track, requester_id); + + if let Err(e) = announce_channel + .send_message( + data.http.as_ref(), + serenity::CreateMessage::default().embed(embed), + ) + .await + { + error!("Failed to send track start announcement: {:?}", e); } } } @@ -83,39 +81,35 @@ pub async fn track_end(client: LavalinkClient, _session_id: String, event: &even if event.reason != events::TrackEndReason::Replaced && event.reason != events::TrackEndReason::Stopped + && let Some(player) = client.get_player_context(event.guild_id) + && let Ok(data) = player.data::() { - if let Some(player) = client.get_player_context(event.guild_id) { - if let Ok(data) = player.data::() { - let config = match crate::database::queries::get_guild_config( - &data.db, - event.guild_id.0 as i64, - ) + let config = + match crate::database::queries::get_guild_config(&data.db, event.guild_id.0 as i64) .await - { - Ok(c) => c, - Err(_) => return, - }; - - if !config.announce_songs { - return; - } + { + Ok(c) => c, + Err(_) => return, + }; - let announce_channel = if let Some(channel_id) = config.announce_channel_id { - serenity::ChannelId::new(channel_id as u64) - } else { - data.channel_id - }; - - let embed = AnnouncementBuilder::track_ended(&event.track); - - let _ = announce_channel - .send_message( - data.http.as_ref(), - serenity::CreateMessage::default().embed(embed), - ) - .await; - } + if !config.announce_songs { + return; } + + let announce_channel = if let Some(channel_id) = config.announce_channel_id { + serenity::ChannelId::new(channel_id as u64) + } else { + data.channel_id + }; + + let embed = AnnouncementBuilder::track_ended(&event.track); + + let _ = announce_channel + .send_message( + data.http.as_ref(), + serenity::CreateMessage::default().embed(embed), + ) + .await; } } @@ -130,24 +124,24 @@ pub async fn track_exception( event.track.info.title, event.exception ); - if let Some(player) = client.get_player_context(event.guild_id) { - if let Ok(data) = player.data::() { - let embed = serenity::CreateEmbed::default() - .title("<:forbidden2:1459603724895780970> Playback Error") - .description(format!( - "Failed to play **{} - {}**\n\nError: {}", - event.track.info.author, event.track.info.title, event.exception.message - )) - .color(COLOR_ERROR); - - let _ = data - .channel_id - .send_message( - data.http.as_ref(), - serenity::CreateMessage::default().embed(embed), - ) - .await; - } + if let Some(player) = client.get_player_context(event.guild_id) + && let Ok(data) = player.data::() + { + let embed = serenity::CreateEmbed::default() + .title("<:forbidden2:1459603724895780970> Playback Error") + .description(format!( + "Failed to play **{} - {}**\n\nError: {}", + event.track.info.author, event.track.info.title, event.exception.message + )) + .color(COLOR_ERROR); + + let _ = data + .channel_id + .send_message( + data.http.as_ref(), + serenity::CreateMessage::default().embed(embed), + ) + .await; } } diff --git a/src/utils/autodisconnect.rs b/src/utils/autodisconnect.rs index 2a41e8f..c3d2994 100644 --- a/src/utils/autodisconnect.rs +++ b/src/utils/autodisconnect.rs @@ -11,11 +11,7 @@ pub struct AutoDisconnectManager { } impl AutoDisconnectManager { - pub fn new( - guild_id: serenity::GuildId, - db: sqlx::SqlitePool, - ctx: serenity::Context, - ) -> Self { + pub fn new(guild_id: serenity::GuildId, db: sqlx::SqlitePool, ctx: serenity::Context) -> Self { Self { guild_id, db, ctx } } diff --git a/src/utils/emojis.rs b/src/utils/emojis.rs index 5190253..ea3ce3c 100644 --- a/src/utils/emojis.rs +++ b/src/utils/emojis.rs @@ -1,5 +1,15 @@ use poise::serenity_prelude as serenity; pub async fn get_emoji(context: &serenity::Context, name: &str) -> Option { - context.http.get_application_emojis().await.ok().and_then(|emojis| emojis.into_iter().map(|emoji| emoji.name).find(|name| name.as_str() == name)) + context + .http + .get_application_emojis() + .await + .ok() + .and_then(|emojis| { + emojis + .into_iter() + .map(|emoji| emoji.name) + .find(|name| name.as_str() == name) + }) } From eb55069015001c4ac37573e04facd4bf53e43758 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:33:02 +0700 Subject: [PATCH 06/15] refactor: refactor various uses of format!() --- src/commands/config.rs | 8 ++++---- src/commands/filters.rs | 2 +- src/commands/play.rs | 6 +++--- src/commands/queue.rs | 2 +- src/commands/remove.rs | 2 +- src/commands/seek.rs | 3 +-- src/commands/skip.rs | 3 +-- src/commands/volume.rs | 2 +- src/utils/announcements.rs | 18 +++++++++--------- src/utils/autodisconnect.rs | 4 ++-- 10 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/commands/config.rs b/src/commands/config.rs index 96ce4a8..95b9b0c 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -35,12 +35,12 @@ pub async fn view(ctx: Context<'_>) -> Result<(), Error> { let config = queries::get_guild_config(db, guild_id).await?; let dj_role = if let Some(role_id) = config.dj_role_id { - format!("<@&{}>", role_id) + format!("<@&{role_id}>") } else { "Not set (Everyone can use music commands)".to_string() }; let announce_channel = if let Some(channel_id) = config.announce_channel_id { - format!("<#{}>", channel_id) + format!("<#{channel_id}>") } else { "Current channel".to_string() }; @@ -121,7 +121,7 @@ async fn volume( "{} Default Volume Updated", volume_emoji.unwrap_or_default() )) - .description(format!("New tracks will play at {}%", vol)) + .description(format!("New tracks will play at {vol}%")) .color(COLOR_SUCCESS); ctx.send(poise::CreateReply::default().embed(embed)).await?; @@ -219,7 +219,7 @@ async fn maxqueue( "{} Max Queue Length Updated", album_emoji.unwrap_or_default() )) - .description(format!("Queue can now hold up to {} tracks", length)) + .description(format!("Queue can now hold up to {length} tracks")) .color(COLOR_SUCCESS); ctx.send(poise::CreateReply::default().embed(embed)).await?; diff --git a/src/commands/filters.rs b/src/commands/filters.rs index 0081354..eab2968 100644 --- a/src/commands/filters.rs +++ b/src/commands/filters.rs @@ -24,7 +24,7 @@ async fn filter_autocomplete( }) .map(|preset| { serenity::AutocompleteChoice::new( - format!("{}", preset.name()), + preset.name().to_string(), preset.name().to_lowercase().replace(" ", "_"), ) }) diff --git a/src/commands/play.rs b/src/commands/play.rs index f99bb1b..bd69da7 100644 --- a/src/commands/play.rs +++ b/src/commands/play.rs @@ -61,9 +61,9 @@ fn format_duration(ms: u64) -> String { let hours = minutes / 60; if hours > 0 { - format!("{}:{:02}:{:02}", hours, minutes % 60, seconds % 60) + format!("{hours}:{:02}:{:02}", minutes % 60, seconds % 60) } else { - format!("{}:{:02}", minutes, seconds % 60) + format!("{minutes}:{:02}", seconds % 60) } } @@ -173,7 +173,7 @@ pub async fn play( "**[{} - {}]({})**", track.info.author, track.info.title, - track.info.uri.as_ref().unwrap_or(&String::from("#")) + track.info.uri.as_deref().unwrap_or("#") )) .field("Duration", duration, true) .field("Requested by", ctx.author().mention().to_string(), true) diff --git a/src/commands/queue.rs b/src/commands/queue.rs index d61a410..7f25dea 100644 --- a/src/commands/queue.rs +++ b/src/commands/queue.rs @@ -52,7 +52,7 @@ pub async fn queue(ctx: Context<'_>) -> Result<(), Error> { }; let embed = serenity::CreateEmbed::default() .title(format!("{} Queue", album_emoji.unwrap_or_default())) - .description(format!("{}**On Queue**:\n{}", now_playing, queue_list)) + .description(format!("{now_playing}**On Queue**:\n{queue_list}")) .color(COLOR_INFO); ctx.send(poise::CreateReply::default().embed(embed)).await?; diff --git a/src/commands/remove.rs b/src/commands/remove.rs index 9adad38..ea06bec 100644 --- a/src/commands/remove.rs +++ b/src/commands/remove.rs @@ -70,7 +70,7 @@ pub async fn remove( "{} Track removed successfully", success_emoji.unwrap_or_default() )) - .description(format!("Removed {} from queue", track_name)) + .description(format!("Removed {track_name} from queue")) .color(COLOR_SUCCESS); let _ = ctx.send(poise::CreateReply::default().embed(embed)); diff --git a/src/commands/seek.rs b/src/commands/seek.rs index 1329af8..03a48f9 100644 --- a/src/commands/seek.rs +++ b/src/commands/seek.rs @@ -33,9 +33,8 @@ pub async fn seek( player.set_position(Duration::from_secs(time)).await?; let embed = serenity::CreateEmbed::default() .title(format!( - "{} Jumped to {}s", + "{} Jumped to {time}s", clock_emoji.await.unwrap_or_default(), - time )) .color(COLOR_SUCCESS); diff --git a/src/commands/skip.rs b/src/commands/skip.rs index ab3ead8..5029de6 100644 --- a/src/commands/skip.rs +++ b/src/commands/skip.rs @@ -63,8 +63,7 @@ pub async fn skip(ctx: Context<'_>) -> Result<(), Error> { .description(format!("**{} - {}**", np.info.author, np.info.title)) .color(COLOR_SUCCESS) .footer(serenity::CreateEmbedFooter::new(format!( - "Skipped by {}", - author_name + "Skipped by {author_name}" ))); ctx.send(poise::CreateReply::default().embed(embed)).await?; diff --git a/src/commands/volume.rs b/src/commands/volume.rs index 6c3a147..b7f82b8 100644 --- a/src/commands/volume.rs +++ b/src/commands/volume.rs @@ -31,7 +31,7 @@ pub async fn volume( let embed = serenity::CreateEmbed::default() .title(format!("{} Volume set", vol_emoji.unwrap_or_default())) - .description(format!("Volume set to {}%", vol)) + .description(format!("Volume set to {vol}%")) .color(COLOR_INFO); ctx.send(poise::CreateReply::default().embed(embed)).await?; diff --git a/src/utils/announcements.rs b/src/utils/announcements.rs index 27c9ac2..5b3a92f 100644 --- a/src/utils/announcements.rs +++ b/src/utils/announcements.rs @@ -18,10 +18,10 @@ impl AnnouncementBuilder { "**[{} - {}]({})**", track.info.author, track.info.title, - track.info.uri.as_ref().unwrap_or(&String::from("#")) + track.info.uri.as_deref().unwrap_or("#") )) .field("Duration", duration, true) - .field("Requested by", format!("<@{}>", requester_id), true) + .field("Requested by", format!("<@{requester_id}>"), true) .color(COLOR_INFO) .timestamp(serenity::Timestamp::now()); @@ -49,11 +49,11 @@ impl AnnouncementBuilder { "**[{} - {}]({})**", track.info.author, track.info.title, - track.info.uri.as_ref().unwrap_or(&String::from("#")) + track.info.uri.as_deref().unwrap_or("#") )) .field("Duration", duration, true) - .field("Position", format!("#{}", position), true) - .field("Requested by", format!("<@{}>", requester_id), true) + .field("Position", format!("#{position}"), true) + .field("Requested by", format!("<@{requester_id}>"), true) .color(COLOR_INFO) .timestamp(serenity::Timestamp::now()); @@ -79,9 +79,9 @@ impl AnnouncementBuilder { ) -> serenity::CreateEmbed { serenity::CreateEmbed::default() .title("<:album:1459594793394114743> Playlist Added") - .description(format!("**{}**", name)) + .description(format!("**{name}**")) .field("Tracks Added", track_count.to_string(), true) - .field("Requested by", format!("<@{}>", requester_id), true) + .field("Requested by", format!("<@{requester_id}>"), true) .color(COLOR_INFO) .timestamp(serenity::Timestamp::now()) } @@ -93,9 +93,9 @@ fn format_duration(ms: u64) -> String { let hours = minutes / 60; if hours > 0 { - format!("{}:{:02}:{:02}", hours, minutes % 60, seconds % 60) + format!("{hours}:{:02}:{:02}", minutes % 60, seconds % 60) } else { - format!("{}:{:02}", minutes, seconds % 60) + format!("{minutes}:{:02}", seconds % 60) } } diff --git a/src/utils/autodisconnect.rs b/src/utils/autodisconnect.rs index c3d2994..80617ac 100644 --- a/src/utils/autodisconnect.rs +++ b/src/utils/autodisconnect.rs @@ -94,8 +94,8 @@ impl AutoDisconnectManager { // Only disconnect if still inactive if player_data.track.is_none() && queue_count == 0 { info!( - "Auto-disconnect: Disconnecting from guild {} after {} seconds of inactivity", - self.guild_id, disconnect_time + "Auto-disconnect: Disconnecting from guild {} after {disconnect_time} seconds of inactivity", + self.guild_id ); let manager = match songbird::get(&self.ctx).await { From e1140f9d59f66951b73fa3109ff1871c9d12eb30 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:37:40 +0700 Subject: [PATCH 07/15] refactor: refactor filter command --- src/commands/filters.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/commands/filters.rs b/src/commands/filters.rs index eab2968..7709d3b 100644 --- a/src/commands/filters.rs +++ b/src/commands/filters.rs @@ -131,18 +131,19 @@ async fn apply( /// List all available filters #[poise::command(slash_command)] async fn list(ctx: Context<'_>) -> Result<(), Error> { - let mut description = String::new(); + let description = FilterPreset::all_presets() + .into_iter() + .map(|preset| { + format!( + "{} **{}**\n{}\n\n", + preset.emoji(), + preset.name(), + preset.description() + ) + }) + .collect::(); let filter_emoji = get_emoji(ctx.serenity_context(), "filter").await; - for preset in FilterPreset::all_presets() { - description.push_str(&format!( - "{} **{}**\n{}\n\n", - preset.emoji(), - preset.name(), - preset.description() - )); - } - let embed = serenity::CreateEmbed::default() .title(format!( "{} Available Audio Filters", @@ -259,10 +260,10 @@ async fn custom( }); if let Some(s) = speed { - changes.push(format!("Speed: {:.2}x", s)); + changes.push(format!("Speed: {s:.2}x")); } if let Some(p) = pitch { - changes.push(format!("Pitch: {:.2}x", p)); + changes.push(format!("Pitch: {p:.2}x")); } } @@ -274,7 +275,7 @@ async fn custom( for i in 0..4 { bands.push((i, clamped)); } - changes.push(format!("Bass: {:+.2}", clamped)); + changes.push(format!("Bass: {clamped:+.2}")); } if let Some(treble_gain) = treble { @@ -282,7 +283,7 @@ async fn custom( for i in 10..15 { bands.push((i, clamped)); } - changes.push(format!("Treble: {:+.2}", clamped)); + changes.push(format!("Treble: {clamped:+.2}")); } let equalizer_bands: Vec = bands From 0e8cb25949b08759316ec999e78512f01a19aa7c Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:46:56 +0700 Subject: [PATCH 08/15] refactor: use a custom equalizer_vec![] macro instead of reconstructing a Vec --- src/utils/filters.rs | 80 +++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 50 deletions(-) diff --git a/src/utils/filters.rs b/src/utils/filters.rs index 4438d47..3d6b438 100644 --- a/src/utils/filters.rs +++ b/src/utils/filters.rs @@ -1,6 +1,12 @@ -use lavalink_rs::model::player::{Equalizer, Filters, Karaoke, Rotation, Timescale}; +use lavalink_rs::model::player::{Filters, Karaoke, Rotation, Timescale}; use serde::{Deserialize, Serialize}; +macro_rules! equalizer_vec { + ($(($band:expr,$gain:expr)),*) => { + vec![$(lavalink_rs::model::player::Equalizer { band: $band, gain: $gain }),*] + }; +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum FilterPreset { Bassboost, @@ -39,19 +45,14 @@ impl FilterPreset { fn bassboost() -> Filters { let mut filters = Filters::default(); - let bands: Vec = vec![ + filters.equalizer = Some(equalizer_vec![ (0, 0.30), (1, 0.30), (2, 0.30), (3, 0.15), (4, 0.15), - (5, 0.15), - ] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - - filters.equalizer = Some(bands); + (5, 0.15) + ]); filters } @@ -72,12 +73,7 @@ impl FilterPreset { pitch: Some(0.85), rate: Some(1.0), }); - - let bands: Vec = vec![(0, 0.20), (1, 0.20), (2, 0.20)] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - filters.equalizer = Some(bands); + filters.equalizer = Some(equalizer_vec![(0, 0.20), (1, 0.20), (2, 0.20)]); filters } @@ -102,13 +98,13 @@ impl FilterPreset { fn treble() -> Filters { let mut filters = Filters::default(); - let bands: Vec = - vec![(10, 0.25), (11, 0.25), (12, 0.25), (13, 0.25), (14, 0.25)] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - - filters.equalizer = Some(bands); + filters.equalizer = Some(equalizer_vec![ + (10, 0.25), + (11, 0.25), + (12, 0.25), + (13, 0.25), + (14, 0.25) + ]); filters } @@ -122,7 +118,7 @@ impl FilterPreset { fn pop() -> Filters { let mut filters = Filters::default(); - let bands: Vec = vec![ + filters.equalizer = Some(equalizer_vec![ (0, -0.02), (1, 0.08), (2, 0.10), @@ -137,18 +133,14 @@ impl FilterPreset { (11, 0.10), (12, 0.10), (13, 0.08), - (14, 0.05), - ] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - filters.equalizer = Some(bands); + (14, 0.05) + ]); filters } fn soft() -> Filters { let mut filters = Filters::default(); - let bands: Vec = vec![ + filters.equalizer = Some(equalizer_vec![ (0, 0.0), (1, 0.0), (2, 0.0), @@ -158,18 +150,14 @@ impl FilterPreset { (6, -0.12), (7, -0.12), (8, -0.10), - (9, -0.08), - ] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - filters.equalizer = Some(bands); + (9, -0.08) + ]); filters } fn electronic() -> Filters { let mut filters = Filters::default(); - let bands: Vec = vec![ + filters.equalizer = Some(equalizer_vec![ (0, 0.15), (1, 0.15), (2, 0.10), @@ -184,18 +172,14 @@ impl FilterPreset { (11, 0.20), (12, 0.20), (13, 0.15), - (14, 0.10), - ] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - filters.equalizer = Some(bands); + (14, 0.10) + ]); filters } fn rock() -> Filters { let mut filters = Filters::default(); - let bands: Vec = vec![ + filters.equalizer = Some(equalizer_vec![ (0, 0.15), (1, 0.10), (2, 0.05), @@ -210,12 +194,8 @@ impl FilterPreset { (11, 0.15), (12, 0.12), (13, 0.10), - (14, 0.08), - ] - .into_iter() - .map(|(band, gain)| Equalizer { band, gain }) - .collect(); - filters.equalizer = Some(bands); + (14, 0.08) + ]); filters } From 99cd77059a119f190e494d4c281d6e5ceac9d6ed Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:51:53 +0700 Subject: [PATCH 09/15] refactor: use ..Default::default() when declaring Filters --- src/utils/filters.rs | 246 ++++++++++++++++++++++--------------------- 1 file changed, 128 insertions(+), 118 deletions(-) diff --git a/src/utils/filters.rs b/src/utils/filters.rs index 3d6b438..6d9527c 100644 --- a/src/utils/filters.rs +++ b/src/utils/filters.rs @@ -44,68 +44,74 @@ impl FilterPreset { } fn bassboost() -> Filters { - let mut filters = Filters::default(); - filters.equalizer = Some(equalizer_vec![ - (0, 0.30), - (1, 0.30), - (2, 0.30), - (3, 0.15), - (4, 0.15), - (5, 0.15) - ]); - filters + Filters { + equalizer: Some(equalizer_vec![ + (0, 0.30), + (1, 0.30), + (2, 0.30), + (3, 0.15), + (4, 0.15), + (5, 0.15) + ]), + ..Default::default() + } } fn nightcore() -> Filters { - let mut filters = Filters::default(); - filters.timescale = Some(Timescale { - speed: Some(1.15), - pitch: Some(1.15), - rate: Some(1.0), - }); - filters + Filters { + timescale: Some(Timescale { + speed: Some(1.15), + pitch: Some(1.15), + rate: Some(1.0), + }), + ..Default::default() + } } fn vaporwave() -> Filters { - let mut filters = Filters::default(); - filters.timescale = Some(Timescale { - speed: Some(0.85), - pitch: Some(0.85), - rate: Some(1.0), - }); - filters.equalizer = Some(equalizer_vec![(0, 0.20), (1, 0.20), (2, 0.20)]); - filters + Filters { + timescale: Some(Timescale { + speed: Some(0.85), + pitch: Some(0.85), + rate: Some(1.0), + }), + equalizer: Some(equalizer_vec![(0, 0.20), (1, 0.20), (2, 0.20)]), + ..Default::default() + } } fn eight_d() -> Filters { - let mut filters = Filters::default(); - filters.rotation = Some(Rotation { - rotation_hz: Some(0.2), - }); - filters + Filters { + rotation: Some(Rotation { + rotation_hz: Some(0.2), + }), + ..Default::default() + } } fn karaoke() -> Filters { - let mut filters = Filters::default(); - filters.karaoke = Some(Karaoke { - level: Some(1.0), - mono_level: Some(1.0), - filter_band: Some(220.0), - filter_width: Some(100.0), - }); - filters + Filters { + karaoke: Some(Karaoke { + level: Some(1.0), + mono_level: Some(1.0), + filter_band: Some(220.0), + filter_width: Some(100.0), + }), + ..Default::default() + } } fn treble() -> Filters { - let mut filters = Filters::default(); - filters.equalizer = Some(equalizer_vec![ - (10, 0.25), - (11, 0.25), - (12, 0.25), - (13, 0.25), - (14, 0.25) - ]); - filters + Filters { + equalizer: Some(equalizer_vec![ + (10, 0.25), + (11, 0.25), + (12, 0.25), + (13, 0.25), + (14, 0.25) + ]), + ..Default::default() + } } fn vibrato() -> Filters { @@ -117,86 +123,90 @@ impl FilterPreset { } fn pop() -> Filters { - let mut filters = Filters::default(); - filters.equalizer = Some(equalizer_vec![ - (0, -0.02), - (1, 0.08), - (2, 0.10), - (3, 0.10), - (4, 0.06), - (5, 0.0), - (6, -0.02), - (7, -0.02), - (8, 0.0), - (9, 0.02), - (10, 0.08), - (11, 0.10), - (12, 0.10), - (13, 0.08), - (14, 0.05) - ]); - filters + Filters { + equalizer: Some(equalizer_vec![ + (0, -0.02), + (1, 0.08), + (2, 0.10), + (3, 0.10), + (4, 0.06), + (5, 0.0), + (6, -0.02), + (7, -0.02), + (8, 0.0), + (9, 0.02), + (10, 0.08), + (11, 0.10), + (12, 0.10), + (13, 0.08), + (14, 0.05) + ]), + ..Default::default() + } } fn soft() -> Filters { - let mut filters = Filters::default(); - filters.equalizer = Some(equalizer_vec![ - (0, 0.0), - (1, 0.0), - (2, 0.0), - (3, 0.0), - (4, -0.05), - (5, -0.10), - (6, -0.12), - (7, -0.12), - (8, -0.10), - (9, -0.08) - ]); - filters + Filters { + equalizer: Some(equalizer_vec![ + (0, 0.0), + (1, 0.0), + (2, 0.0), + (3, 0.0), + (4, -0.05), + (5, -0.10), + (6, -0.12), + (7, -0.12), + (8, -0.10), + (9, -0.08) + ]), + ..Default::default() + } } fn electronic() -> Filters { - let mut filters = Filters::default(); - filters.equalizer = Some(equalizer_vec![ - (0, 0.15), - (1, 0.15), - (2, 0.10), - (3, 0.05), - (4, 0.0), - (5, -0.05), - (6, -0.05), - (7, 0.0), - (8, 0.05), - (9, 0.10), - (10, 0.15), - (11, 0.20), - (12, 0.20), - (13, 0.15), - (14, 0.10) - ]); - filters + Filters { + equalizer: Some(equalizer_vec![ + (0, 0.15), + (1, 0.15), + (2, 0.10), + (3, 0.05), + (4, 0.0), + (5, -0.05), + (6, -0.05), + (7, 0.0), + (8, 0.05), + (9, 0.10), + (10, 0.15), + (11, 0.20), + (12, 0.20), + (13, 0.15), + (14, 0.10) + ]), + ..Default::default() + } } fn rock() -> Filters { - let mut filters = Filters::default(); - filters.equalizer = Some(equalizer_vec![ - (0, 0.15), - (1, 0.10), - (2, 0.05), - (3, 0.02), - (4, -0.02), - (5, -0.05), - (6, -0.03), - (7, 0.05), - (8, 0.10), - (9, 0.12), - (10, 0.15), - (11, 0.15), - (12, 0.12), - (13, 0.10), - (14, 0.08) - ]); - filters + Filters { + equalizer: Some(equalizer_vec![ + (0, 0.15), + (1, 0.10), + (2, 0.05), + (3, 0.02), + (4, -0.02), + (5, -0.05), + (6, -0.03), + (7, 0.05), + (8, 0.10), + (9, 0.12), + (10, 0.15), + (11, 0.15), + (12, 0.12), + (13, 0.10), + (14, 0.08) + ]), + ..Default::default() + } } pub fn name(&self) -> &str { From fb3b79e26844396faf580118c1b21bfed7cb264a Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:53:30 +0700 Subject: [PATCH 10/15] refactor: refactor filter preset methods than matches against self --- src/utils/filters.rs | 138 +++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/utils/filters.rs b/src/utils/filters.rs index 6d9527c..1ba8e17 100644 --- a/src/utils/filters.rs +++ b/src/utils/filters.rs @@ -27,19 +27,19 @@ pub enum FilterPreset { impl FilterPreset { pub fn to_filters(&self) -> Filters { match self { - FilterPreset::Bassboost => Self::bassboost(), - FilterPreset::Nightcore => Self::nightcore(), - FilterPreset::Vaporwave => Self::vaporwave(), - FilterPreset::EightD => Self::eight_d(), - FilterPreset::Karaoke => Self::karaoke(), - FilterPreset::Treble => Self::treble(), - FilterPreset::Vibrato => Self::vibrato(), - FilterPreset::Tremolo => Self::tremolo(), - FilterPreset::Pop => Self::pop(), - FilterPreset::Soft => Self::soft(), - FilterPreset::Electronic => Self::electronic(), - FilterPreset::Rock => Self::rock(), - FilterPreset::Clear => Filters::default(), + Self::Bassboost => Self::bassboost(), + Self::Nightcore => Self::nightcore(), + Self::Vaporwave => Self::vaporwave(), + Self::EightD => Self::eight_d(), + Self::Karaoke => Self::karaoke(), + Self::Treble => Self::treble(), + Self::Vibrato => Self::vibrato(), + Self::Tremolo => Self::tremolo(), + Self::Pop => Self::pop(), + Self::Soft => Self::soft(), + Self::Electronic => Self::electronic(), + Self::Rock => Self::rock(), + Self::Clear => Filters::default(), } } @@ -209,75 +209,75 @@ impl FilterPreset { } } - pub fn name(&self) -> &str { + pub const fn name(&self) -> &str { match self { - FilterPreset::Bassboost => "Bass Boost", - FilterPreset::Nightcore => "Nightcore", - FilterPreset::Vaporwave => "Vaporwave", - FilterPreset::EightD => "8D Audio", - FilterPreset::Karaoke => "Karaoke", - FilterPreset::Treble => "Treble Boost", - FilterPreset::Vibrato => "Vibrato", - FilterPreset::Tremolo => "Tremolo", - FilterPreset::Pop => "Pop", - FilterPreset::Soft => "Soft", - FilterPreset::Electronic => "Electronic", - FilterPreset::Rock => "Rock", - FilterPreset::Clear => "Clear (No Filters)", + Self::Bassboost => "Bass Boost", + Self::Nightcore => "Nightcore", + Self::Vaporwave => "Vaporwave", + Self::EightD => "8D Audio", + Self::Karaoke => "Karaoke", + Self::Treble => "Treble Boost", + Self::Vibrato => "Vibrato", + Self::Tremolo => "Tremolo", + Self::Pop => "Pop", + Self::Soft => "Soft", + Self::Electronic => "Electronic", + Self::Rock => "Rock", + Self::Clear => "Clear (No Filters)", } } - pub fn description(&self) -> &str { + pub const fn description(&self) -> &str { match self { - FilterPreset::Bassboost => "Amplifies low frequencies for extra bass", - FilterPreset::Nightcore => "Increases speed and pitch for that nightcore feel", - FilterPreset::Vaporwave => "Slows down speed and pitch for a dreamy vibe", - FilterPreset::EightD => "Creates a rotating audio effect around your head", - FilterPreset::Karaoke => "Reduces vocals for karaoke sessions", - FilterPreset::Treble => "Amplifies high frequencies", - FilterPreset::Vibrato => "Adds a vibrating pitch effect", - FilterPreset::Tremolo => "Adds a trembling volume effect", - FilterPreset::Pop => "Optimized for pop music", - FilterPreset::Soft => "Reduces harsh frequencies for a softer sound", - FilterPreset::Electronic => "Enhanced for electronic/EDM music", - FilterPreset::Rock => "Optimized for rock music", - FilterPreset::Clear => "Removes all audio filters", + Self::Bassboost => "Amplifies low frequencies for extra bass", + Self::Nightcore => "Increases speed and pitch for that nightcore feel", + Self::Vaporwave => "Slows down speed and pitch for a dreamy vibe", + Self::EightD => "Creates a rotating audio effect around your head", + Self::Karaoke => "Reduces vocals for karaoke sessions", + Self::Treble => "Amplifies high frequencies", + Self::Vibrato => "Adds a vibrating pitch effect", + Self::Tremolo => "Adds a trembling volume effect", + Self::Pop => "Optimized for pop music", + Self::Soft => "Reduces harsh frequencies for a softer sound", + Self::Electronic => "Enhanced for electronic/EDM music", + Self::Rock => "Optimized for rock music", + Self::Clear => "Removes all audio filters", } } - pub fn emoji(&self) -> &str { + pub const fn emoji(&self) -> &str { match self { - FilterPreset::Bassboost => "<:vol3:1459594782920671373>", - FilterPreset::Nightcore => "<:thunder:1460010342095524048>", - FilterPreset::Vaporwave => "<:cloud:1460010003594481946>", - FilterPreset::EightD => "<:headphones:1459594791577714738>", - FilterPreset::Karaoke => "<:song:1459594788998348875>", - FilterPreset::Treble => "<:musicnotes:1459594797634293811>", - FilterPreset::Vibrato => "<:star:1460009999513161914>", - FilterPreset::Tremolo => "<:magnet:1460010859521773628>", - FilterPreset::Pop => "<:musicnotes:1459594797634293811>", - FilterPreset::Soft => "<:sprout:1460010703728676994>", - FilterPreset::Electronic => "<:thunder:1460010342095524048>", - FilterPreset::Rock => "<:fire:1460010340862656616>", - FilterPreset::Clear => "<:stars:1460010000784298147>", + Self::Bassboost => "<:vol3:1459594782920671373>", + Self::Nightcore => "<:thunder:1460010342095524048>", + Self::Vaporwave => "<:cloud:1460010003594481946>", + Self::EightD => "<:headphones:1459594791577714738>", + Self::Karaoke => "<:song:1459594788998348875>", + Self::Treble => "<:musicnotes:1459594797634293811>", + Self::Vibrato => "<:star:1460009999513161914>", + Self::Tremolo => "<:magnet:1460010859521773628>", + Self::Pop => "<:musicnotes:1459594797634293811>", + Self::Soft => "<:sprout:1460010703728676994>", + Self::Electronic => "<:thunder:1460010342095524048>", + Self::Rock => "<:fire:1460010340862656616>", + Self::Clear => "<:stars:1460010000784298147>", } } - pub fn all_presets() -> Vec { + pub fn all_presets() -> Vec { vec![ - FilterPreset::Bassboost, - FilterPreset::Nightcore, - FilterPreset::Vaporwave, - FilterPreset::EightD, - FilterPreset::Karaoke, - FilterPreset::Treble, - FilterPreset::Vibrato, - FilterPreset::Tremolo, - FilterPreset::Pop, - FilterPreset::Soft, - FilterPreset::Electronic, - FilterPreset::Rock, - FilterPreset::Clear, + Self::Bassboost, + Self::Nightcore, + Self::Vaporwave, + Self::EightD, + Self::Karaoke, + Self::Treble, + Self::Vibrato, + Self::Tremolo, + Self::Pop, + Self::Soft, + Self::Electronic, + Self::Rock, + Self::Clear, ] } } From f43e0d270697c1293d8cd453aba1cf46a295bf86 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:59:55 +0700 Subject: [PATCH 11/15] refactor: apply several miscellaneous refactors and fixes --- src/commands/remove.rs | 2 +- src/main.rs | 4 +++- src/utils/autodisconnect.rs | 6 +++++- src/utils/emojis.rs | 4 ++-- src/utils/player_data.rs | 2 +- src/utils/voicechannel.rs | 25 ++++++++++--------------- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/commands/remove.rs b/src/commands/remove.rs index ea06bec..8676c08 100644 --- a/src/commands/remove.rs +++ b/src/commands/remove.rs @@ -73,7 +73,7 @@ pub async fn remove( .description(format!("Removed {track_name} from queue")) .color(COLOR_SUCCESS); - let _ = ctx.send(poise::CreateReply::default().embed(embed)); + let _ = ctx.send(poise::CreateReply::default().embed(embed)).await; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 6974db6..ee1dbf0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,7 +60,9 @@ impl serenity::EventHandler for Handler { } }; let _activity = set_guild_activity(&ctx); - let _ = channel_id.send_message(ctx.http, serenity::CreateMessage::default().embed(embed)); + let _ = channel_id + .send_message(ctx.http, serenity::CreateMessage::default().embed(embed)) + .await; } } diff --git a/src/utils/autodisconnect.rs b/src/utils/autodisconnect.rs index 80617ac..2d39b3d 100644 --- a/src/utils/autodisconnect.rs +++ b/src/utils/autodisconnect.rs @@ -11,7 +11,11 @@ pub struct AutoDisconnectManager { } impl AutoDisconnectManager { - pub fn new(guild_id: serenity::GuildId, db: sqlx::SqlitePool, ctx: serenity::Context) -> Self { + pub const fn new( + guild_id: serenity::GuildId, + db: sqlx::SqlitePool, + ctx: serenity::Context, + ) -> Self { Self { guild_id, db, ctx } } diff --git a/src/utils/emojis.rs b/src/utils/emojis.rs index ea3ce3c..8c30542 100644 --- a/src/utils/emojis.rs +++ b/src/utils/emojis.rs @@ -1,6 +1,6 @@ use poise::serenity_prelude as serenity; -pub async fn get_emoji(context: &serenity::Context, name: &str) -> Option { +pub async fn get_emoji(context: &serenity::Context, input_name: &str) -> Option { context .http .get_application_emojis() @@ -10,6 +10,6 @@ pub async fn get_emoji(context: &serenity::Context, name: &str) -> Option, db: sqlx::SqlitePool, diff --git a/src/utils/voicechannel.rs b/src/utils/voicechannel.rs index 872eaac..b4b6136 100644 --- a/src/utils/voicechannel.rs +++ b/src/utils/voicechannel.rs @@ -64,21 +64,20 @@ pub async fn _join( ); auto_disconnect.start_monitoring(lava_client.clone()).await; - let stage = match connect_to + let stage = connect_to .get_stage_instance(ctx.serenity_context().http.clone()) .await - { - Ok(_) => true, - Err(_) => false, - }; + .is_ok(); if stage { let http = ctx.serenity_context().http.clone(); let channels = guild_id.channels(http).await.unwrap(); let channel = channels.get(&channel_id.unwrap()).unwrap(); - let _ = channel.edit_own_voice_state( - ctx.serenity_context().http(), - EditVoiceState::new().request_to_speak(true), - ); + let _ = channel + .edit_own_voice_state( + ctx.serenity_context().http(), + EditVoiceState::new().request_to_speak(true), + ) + .await; } return Ok(true); } @@ -95,11 +94,7 @@ pub fn check_user_in_voice(ctx: &Context<'_>, guild_id: serenity::GuildId) -> Re let cache = ctx.cache().expect("Expected cache"); let user_voice = cache .guild(guild_id) - .and_then(|g| { - g.voice_states - .get(&ctx.author().id) - .map(|vs| vs.channel_id.clone()) - }) + .and_then(|g| g.voice_states.get(&ctx.author().id).map(|vs| vs.channel_id)) .flatten(); let bot_voice = cache @@ -107,7 +102,7 @@ pub fn check_user_in_voice(ctx: &Context<'_>, guild_id: serenity::GuildId) -> Re .and_then(|g| { g.voice_states .get(&cache.current_user().id) - .map(|vs| vs.channel_id.clone()) + .map(|vs| vs.channel_id) }) .flatten(); From 9a04e13c3006a8e1d164b613d32c2833699084c8 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:01:57 +0700 Subject: [PATCH 12/15] refactor: use a constant instead of creating a Vec<> every time with filter presets all --- src/commands/filters.rs | 4 ++-- src/utils/filters.rs | 34 ++++++++++++++++------------------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/commands/filters.rs b/src/commands/filters.rs index 7709d3b..a5aaaa2 100644 --- a/src/commands/filters.rs +++ b/src/commands/filters.rs @@ -14,7 +14,7 @@ async fn filter_autocomplete( _ctx: Context<'_>, partial: &str, ) -> Vec { - FilterPreset::all_presets() + FilterPreset::ALL .iter() .filter(|preset| { preset @@ -131,7 +131,7 @@ async fn apply( /// List all available filters #[poise::command(slash_command)] async fn list(ctx: Context<'_>) -> Result<(), Error> { - let description = FilterPreset::all_presets() + let description = FilterPreset::ALL .into_iter() .map(|preset| { format!( diff --git a/src/utils/filters.rs b/src/utils/filters.rs index 1ba8e17..101d452 100644 --- a/src/utils/filters.rs +++ b/src/utils/filters.rs @@ -25,6 +25,22 @@ pub enum FilterPreset { } impl FilterPreset { + pub const ALL: [Self; 13] = [ + Self::Bassboost, + Self::Nightcore, + Self::Vaporwave, + Self::EightD, + Self::Karaoke, + Self::Treble, + Self::Vibrato, + Self::Tremolo, + Self::Pop, + Self::Soft, + Self::Electronic, + Self::Rock, + Self::Clear, + ]; + pub fn to_filters(&self) -> Filters { match self { Self::Bassboost => Self::bassboost(), @@ -262,22 +278,4 @@ impl FilterPreset { Self::Clear => "<:stars:1460010000784298147>", } } - - pub fn all_presets() -> Vec { - vec![ - Self::Bassboost, - Self::Nightcore, - Self::Vaporwave, - Self::EightD, - Self::Karaoke, - Self::Treble, - Self::Vibrato, - Self::Tremolo, - Self::Pop, - Self::Soft, - Self::Electronic, - Self::Rock, - Self::Clear, - ] - } } From bcc8ecf8ef8672f483aca81619cb605139a6f472 Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:06:11 +0700 Subject: [PATCH 13/15] feat: add FromStr for filter presets --- src/commands/filters.rs | 18 +----------------- src/utils/filters.rs | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/commands/filters.rs b/src/commands/filters.rs index a5aaaa2..8f7da8d 100644 --- a/src/commands/filters.rs +++ b/src/commands/filters.rs @@ -92,23 +92,7 @@ async fn apply( .get_player_context(guild_id) .ok_or("Not connected to voice channel")?; - let filter_preset = match preset.as_str() { - "bass_boost" => FilterPreset::Bassboost, - "nightcore" => FilterPreset::Nightcore, - "vaporwave" => FilterPreset::Vaporwave, - "8d_audio" => FilterPreset::EightD, - "karaoke" => FilterPreset::Karaoke, - "treble_boost" => FilterPreset::Treble, - "vibrato" => FilterPreset::Vibrato, - "tremolo" => FilterPreset::Tremolo, - "pop" => FilterPreset::Pop, - "soft" => FilterPreset::Soft, - "electronic" => FilterPreset::Electronic, - "rock" => FilterPreset::Rock, - "clear_(no_filters)" => FilterPreset::Clear, - _ => return Err("Invalid filter preset".into()), - }; - + let filter_preset = preset.parse::()?; let filters = filter_preset.to_filters(); player.set_filters(filters).await?; diff --git a/src/utils/filters.rs b/src/utils/filters.rs index 101d452..2f647fb 100644 --- a/src/utils/filters.rs +++ b/src/utils/filters.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use lavalink_rs::model::player::{Filters, Karaoke, Rotation, Timescale}; use serde::{Deserialize, Serialize}; @@ -279,3 +281,26 @@ impl FilterPreset { } } } + +impl FromStr for FilterPreset { + type Err = crate::Error; + + fn from_str(s: &str) -> Result { + Ok(match s { + "bass_boost" => Self::Bassboost, + "nightcore" => Self::Nightcore, + "vaporwave" => Self::Vaporwave, + "8d_audio" => Self::EightD, + "karaoke" => Self::Karaoke, + "treble_boost" => Self::Treble, + "vibrato" => Self::Vibrato, + "tremolo" => Self::Tremolo, + "pop" => Self::Pop, + "soft" => Self::Soft, + "electronic" => Self::Electronic, + "rock" => Self::Rock, + "clear_(no_filters)" => Self::Clear, + _ => return Err("Invalid filter preset".into()), + }) + } +} From cb25a2419368620648929e5f33f62b37c503bffb Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:10:57 +0700 Subject: [PATCH 14/15] refactor: use unwrap_or_default whenever possible --- src/music_events.rs | 2 +- src/utils/autodisconnect.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/music_events.rs b/src/music_events.rs index c02063c..1ec47b2 100644 --- a/src/music_events.rs +++ b/src/music_events.rs @@ -56,7 +56,7 @@ pub async fn track_start(client: LavalinkClient, _session_id: String, event: &ev .user_data .as_ref() .and_then(|d| d["requester_id"].as_u64()) - .unwrap_or(0); + .unwrap_or_default(); let embed = AnnouncementBuilder::now_playing(&event.track, requester_id); diff --git a/src/utils/autodisconnect.rs b/src/utils/autodisconnect.rs index 2d39b3d..42c204f 100644 --- a/src/utils/autodisconnect.rs +++ b/src/utils/autodisconnect.rs @@ -149,7 +149,7 @@ impl AutoDisconnectManager { members_in_channel.is_empty() || members_in_channel .iter() - .all(|(user_id, _)| cache.user(**user_id).map(|u| u.bot).unwrap_or(false)) + .all(|(user_id, _)| cache.user(**user_id).map(|u| u.bot).unwrap_or_default()) } else { false } From ae46f3dd8b90a0207f8ed02bce628a4955b7181a Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:27:02 +0700 Subject: [PATCH 15/15] refactor: collapse single-use variable --- src/utils/voicechannel.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/voicechannel.rs b/src/utils/voicechannel.rs index b4b6136..a84bbef 100644 --- a/src/utils/voicechannel.rs +++ b/src/utils/voicechannel.rs @@ -64,11 +64,11 @@ pub async fn _join( ); auto_disconnect.start_monitoring(lava_client.clone()).await; - let stage = connect_to + if connect_to .get_stage_instance(ctx.serenity_context().http.clone()) .await - .is_ok(); - if stage { + .is_ok() + { let http = ctx.serenity_context().http.clone(); let channels = guild_id.channels(http).await.unwrap(); let channel = channels.get(&channel_id.unwrap()).unwrap();