From a61b003c4b3083f59d59536d279e5f0e9229806f Mon Sep 17 00:00:00 2001 From: circuitsacul Date: Thu, 23 Jul 2026 22:20:54 -0400 Subject: [PATCH 1/2] refactor: use LazyLock instead of lazy_static --- Cargo.lock | 1 - Cargo.toml | 1 - src/core/embedder/attachment_handle.rs | 20 +++++++++----------- src/core/embedder/builder.rs | 11 +++++------ src/core/embedder/gifv.rs | 18 +++++++----------- src/core/embedder/imgur.rs | 10 +++++----- src/core/emoji.rs | 7 ++----- src/database/validation/cooldown.rs | 10 +++++----- src/database/validation/mentions.rs | 8 +++----- src/database/validation/time_delta.rs | 8 +++----- src/utils/message_link.rs | 8 +++----- 11 files changed, 42 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4eb1e20..0c0c0ba8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2938,7 +2938,6 @@ dependencies = [ "floodgate", "futures", "humantime", - "lazy_static", "moka", "psutil", "regex", diff --git a/Cargo.toml b/Cargo.toml index 17766334..0501efb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ emojis = "0.8.0" floodgate = "0.5.1" futures = "0.3.31" humantime = "2.3.0" -lazy_static = "1.5.0" moka = { version = "0.11.3", features = ["future"] } psutil = "3.3.0" regex = "1.12.2" diff --git a/src/core/embedder/attachment_handle.rs b/src/core/embedder/attachment_handle.rs index e652a204..69167c08 100644 --- a/src/core/embedder/attachment_handle.rs +++ b/src/core/embedder/attachment_handle.rs @@ -1,5 +1,7 @@ +use std::sync::LazyLock; + use async_trait::async_trait; -use lazy_static::lazy_static; +use regex::Regex; use twilight_model::{ channel::{Attachment as ReceivedAttachment, message::embed::Embed}, http::attachment::Attachment, @@ -27,17 +29,13 @@ impl AttachmentHandle { ) -> StarboardResult> { // this should always be a proxy url, but we do this to make 100% // sure that there isn't a bug that could potentially leak the VPS ip. - { - lazy_static! { - static ref RE: regex::Regex = regex::Regex::new( - r#"^https://[\w\.\-]*\.(discord\.com|discordapp\.com|discordapp.net)"# - ) - .unwrap(); - } + static RE: LazyLock = LazyLock::new(|| { + Regex::new(r#"^https://[\w\.\-]*\.(discord\.com|discordapp\.com|discordapp.net)"#) + .unwrap() + }); - if !RE.is_match(&self.url) { - return Ok(None); - } + if !RE.is_match(&self.url) { + return Ok(None); } // we only want to download files under 8mb diff --git a/src/core/embedder/builder.rs b/src/core/embedder/builder.rs index 5258d42f..e8459bb0 100644 --- a/src/core/embedder/builder.rs +++ b/src/core/embedder/builder.rs @@ -1,6 +1,5 @@ -use std::fmt::Write; +use std::{fmt::Write, sync::LazyLock}; -use lazy_static::lazy_static; use regex::Regex; use twilight_model::{ channel::message::{ @@ -29,13 +28,13 @@ use crate::{ }, }; -lazy_static! { - static ref URL_REGEX: Regex = Regex::new(concat!( +static URL_REGEX: LazyLock = LazyLock::new(|| { + Regex::new(concat!( r"^https?://(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]", r"{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&/=]*)$" )) - .unwrap(); -} + .unwrap() +}); pub struct FullBuiltStarboardEmbed { pub top_content: String, diff --git a/src/core/embedder/gifv.rs b/src/core/embedder/gifv.rs index c0f136bb..281ef021 100644 --- a/src/core/embedder/gifv.rs +++ b/src/core/embedder/gifv.rs @@ -1,18 +1,14 @@ -use std::str::FromStr; +use std::{str::FromStr, sync::LazyLock}; -use lazy_static::lazy_static; +use regex::Regex; use reqwest::Url; pub fn get_gif_url(url: &str, provider: &str) -> Option { - lazy_static! { - static ref TENOR: regex::Regex = - regex::Regex::new(r#"^https://media\.tenor\.com?/(.+)/(.*)\.\w+$"#).unwrap(); - } - lazy_static! { - static ref GIPHY: regex::Regex = - regex::Regex::new(r#"^https://media\d*\.giphy\.com/media/([\w-]+)/(.*)\.gif$"#) - .unwrap(); - } + static TENOR: LazyLock = + LazyLock::new(|| Regex::new(r#"^https://media\.tenor\.com?/(.+)/(.*)\.\w+$"#).unwrap()); + static GIPHY: LazyLock = LazyLock::new(|| { + Regex::new(r#"^https://media\d*\.giphy\.com/media/([\w-]+)/(.*)\.gif$"#).unwrap() + }); match provider { "Tenor" => { diff --git a/src/core/embedder/imgur.rs b/src/core/embedder/imgur.rs index b7403a12..f437bf74 100644 --- a/src/core/embedder/imgur.rs +++ b/src/core/embedder/imgur.rs @@ -1,4 +1,6 @@ -use lazy_static::lazy_static; +use std::sync::LazyLock; + +use regex::Regex; use twilight_model::channel::message::{Embed, embed::EmbedImage}; use super::AttachmentHandle; @@ -36,10 +38,8 @@ pub fn modify_imgur_embed(mut embed: Embed) -> ImgurResult { } pub fn modify_imgur_url(url: &str) -> Option { - lazy_static! { - static ref RE: regex::Regex = - regex::Regex::new(r#"https://i\.imgur\.com/(\w+)\.(\w+)"#).unwrap(); - } + static RE: LazyLock = + LazyLock::new(|| Regex::new(r#"https://i\.imgur\.com/(\w+)\.(\w+)"#).unwrap()); let caps: Vec<_> = RE.captures_iter(url).collect(); let groups = caps.first()?; diff --git a/src/core/emoji.rs b/src/core/emoji.rs index dd333669..ebd1d2b5 100644 --- a/src/core/emoji.rs +++ b/src/core/emoji.rs @@ -1,6 +1,5 @@ -use std::str::FromStr; +use std::{str::FromStr, sync::LazyLock}; -use lazy_static::lazy_static; use regex::Regex; use twilight_http::request::channel::reaction::RequestReactionType; use twilight_mention::Mention; @@ -57,9 +56,7 @@ impl SimpleEmoji { bot: &StarboardBot, guild_id: Id, ) -> Vec { - lazy_static! { - static ref CUSTOM: Regex = Regex::new(r"^\d{10,}").unwrap(); - } + static CUSTOM: LazyLock = LazyLock::new(|| Regex::new(r"^\d{10,}").unwrap()); let mut emojis = Vec::new(); diff --git a/src/database/validation/cooldown.rs b/src/database/validation/cooldown.rs index 4f0e3707..a4aa11af 100644 --- a/src/database/validation/cooldown.rs +++ b/src/database/validation/cooldown.rs @@ -1,10 +1,10 @@ -use lazy_static::lazy_static; +use std::sync::LazyLock; + +use regex::Regex; pub fn parse_cooldown(inp: &str) -> Result<(i16, i16), String> { - lazy_static! { - static ref RE: regex::Regex = - regex::Regex::new(r#"(?P\d+).+?(?P\d+)"#).unwrap(); - } + static RE: LazyLock = + LazyLock::new(|| Regex::new(r#"(?P\d+).+?(?P\d+)"#).unwrap()); let found = match RE.captures(inp) { None => { diff --git a/src/database/validation/mentions.rs b/src/database/validation/mentions.rs index 3f1baae9..3e8cd1fc 100644 --- a/src/database/validation/mentions.rs +++ b/src/database/validation/mentions.rs @@ -1,8 +1,8 @@ //! Parsing and validation for different types of mentions. -use std::{collections::HashSet, str::FromStr}; +use std::{collections::HashSet, str::FromStr, sync::LazyLock}; -use lazy_static::lazy_static; +use regex::Regex; use twilight_model::id::{Id, marker::GuildMarker}; use crate::{client::bot::StarboardBot, errors::StarboardResult, utils::id_as_i64::GetI64}; @@ -12,9 +12,7 @@ where IdT: FromStr, ::Err: std::fmt::Debug, { - lazy_static! { - static ref RE: regex::Regex = regex::Regex::new(r#"\d+"#).unwrap(); - } + static RE: LazyLock = LazyLock::new(|| Regex::new(r#"\d+"#).unwrap()); RE.find_iter(inp).map(|val| val.as_str().parse().unwrap()) } diff --git a/src/database/validation/time_delta.rs b/src/database/validation/time_delta.rs index 03c9917e..bd94aeac 100644 --- a/src/database/validation/time_delta.rs +++ b/src/database/validation/time_delta.rs @@ -1,6 +1,5 @@ -use std::{borrow::Cow, time::Duration}; +use std::{borrow::Cow, sync::LazyLock, time::Duration}; -use lazy_static::lazy_static; use regex::Regex; use crate::constants; @@ -36,9 +35,8 @@ fn unit_conversion(unit: &str) -> Option { } pub fn parse_time_delta(inp: &str) -> Result { - lazy_static! { - static ref RE: Regex = Regex::new(r#"^(?P\d+)(?P\w+)$"#).unwrap(); - } + static RE: LazyLock = + LazyLock::new(|| Regex::new(r#"^(?P\d+)(?P\w+)$"#).unwrap()); let mut seconds = 0; let mut carry = None; diff --git a/src/utils/message_link.rs b/src/utils/message_link.rs index c8024a88..c7ed96f9 100644 --- a/src/utils/message_link.rs +++ b/src/utils/message_link.rs @@ -1,6 +1,5 @@ -use std::fmt::Display; +use std::{fmt::Display, sync::LazyLock}; -use lazy_static::lazy_static; use regex::Regex; pub fn parse_message_link(link: &str) -> Option<(i64, i64)> { @@ -17,9 +16,8 @@ pub fn parse_message_link(link: &str) -> Option<(i64, i64)> { return Some((channel_id, message_id)); } - lazy_static! { - static ref RE: Regex = Regex::new(r#"/channels/(\d+)/(\d+)/(\d+)"#).unwrap(); - } + static RE: LazyLock = + LazyLock::new(|| Regex::new(r#"/channels/(\d+)/(\d+)/(\d+)"#).unwrap()); let ret = RE.captures(link)?; From 036f19cd0caf6b404d1eb9494be6d96e12e1eb76 Mon Sep 17 00:00:00 2001 From: circuitsacul Date: Thu, 23 Jul 2026 22:29:47 -0400 Subject: [PATCH 2/2] feat: klipy GIF support --- src/core/embedder/gifv.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/embedder/gifv.rs b/src/core/embedder/gifv.rs index 281ef021..ef84283d 100644 --- a/src/core/embedder/gifv.rs +++ b/src/core/embedder/gifv.rs @@ -49,6 +49,7 @@ pub fn get_gif_url(url: &str, provider: &str) -> Option { Some(format!("{origin}/{gif_id}-size_restricted.gif")) } + "Klipy" => Some(url.to_owned()), // I take back everything bad I said about klipy other => { eprintln!("Unkown GIFV provider: {other}\n{url}"); None