From 90805674c68fba7f76b9b88e423936f46c7584b2 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Mon, 27 Oct 2025 11:51:15 +0200 Subject: [PATCH] refactor(handlers): make lazy_regex macro --- src/handlers/instagram.rs | 19 ++++++------------- src/handlers/mod.rs | 11 +++++++++++ src/handlers/tiktok.rs | 17 ++++++----------- src/handlers/twitter.rs | 19 ++++++------------- src/handlers/youtube.rs | 17 ++++++----------- 5 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/handlers/instagram.rs b/src/handlers/instagram.rs index 61122d7..0b60962 100644 --- a/src/handlers/instagram.rs +++ b/src/handlers/instagram.rs @@ -1,21 +1,14 @@ use crate::download::{download_instagram, process_download_result}; use crate::error::Result; use crate::handlers::SocialHandler; -use regex::Regex; -use std::sync::OnceLock; +use crate::lazy_regex; use teloxide::{Bot, types::ChatId}; use tracing::info; -static SHORTCODE_RE: OnceLock = OnceLock::new(); - -fn shortcode_regex() -> &'static Regex { - SHORTCODE_RE.get_or_init(|| { - Regex::new( - r"https?://(?:www\.)?(?:instagram\.com|instagr\.am)/(?:p|reel|tv)/([A-Za-z0-9_-]+)", - ) - .expect("filed to compile regex") - }) -} +lazy_regex!( + URL_RE, + r#"https?://(?:www\.)?(?:instagram\.com|instagr\.am)/(?:p|reel|tv)/([A-Za-z0-9_-]+)"# +); /// Handler for Instagram posts / reels / tv #[derive(Clone, Default)] @@ -36,7 +29,7 @@ impl SocialHandler for InstagramHandler { } fn try_extract(&self, text: &str) -> Option { - shortcode_regex() + regex() .captures(text) .and_then(|c| c.get(0).map(|m| m.as_str().to_owned())) } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index fc21774..302e660 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -19,6 +19,17 @@ pub use twitter::TwitterHandler; #[cfg(feature = "youtube")] pub use youtube::YouTubeShortsHandler; +#[macro_export] +macro_rules! lazy_regex { + ($name:ident, $pattern:expr) => { + static $name: std::sync::OnceLock = std::sync::OnceLock::new(); + + fn regex() -> &'static regex::Regex { + $name.get_or_init(|| regex::Regex::new($pattern).expect("failed to compile regex")) + } + }; +} + #[async_trait::async_trait] pub trait SocialHandler: Send + Sync { /// Short name used for logging etc. diff --git a/src/handlers/tiktok.rs b/src/handlers/tiktok.rs index 784e482..747e830 100644 --- a/src/handlers/tiktok.rs +++ b/src/handlers/tiktok.rs @@ -1,22 +1,17 @@ use crate::{ download::{download_tiktok, process_download_result}, error::Result, + lazy_regex, }; -use regex::Regex; -use std::sync::OnceLock; use teloxide::{Bot, types::ChatId}; use tracing::info; use crate::handlers::SocialHandler; -static SHORTCODE_RE: OnceLock = OnceLock::new(); - -fn shortcode_regex() -> &'static Regex { - SHORTCODE_RE.get_or_init(|| { - Regex::new(r"https?://(?:www\.)?(?:vm|vt|tt|tik)\.tiktok\.com/([A-Za-z0-9_-]+)[/?#]?") - .expect("filed to compile regex") - }) -} +lazy_regex!( + URL_RE, + r#"https?://(?:www\.)?(?:vm|vt|tt|tik)\.tiktok\.com/([A-Za-z0-9_-]+)[/?#]?"# +); /// Handler for Tiktok #[derive(Clone, Default)] @@ -37,7 +32,7 @@ impl SocialHandler for TiktokHandler { } fn try_extract(&self, text: &str) -> Option { - shortcode_regex() + regex() .captures(text) .and_then(|c| c.get(0).map(|m| m.as_str().to_owned())) } diff --git a/src/handlers/twitter.rs b/src/handlers/twitter.rs index 20dbb8a..a02790b 100644 --- a/src/handlers/twitter.rs +++ b/src/handlers/twitter.rs @@ -1,24 +1,17 @@ use crate::{ download::{download_twitter, process_download_result}, error::Result, + lazy_regex, }; -use regex::Regex; -use std::sync::OnceLock; use teloxide::{Bot, types::ChatId}; use tracing::info; use crate::handlers::SocialHandler; -static SHORTCODE_RE: OnceLock = OnceLock::new(); - -fn shortcode_regex() -> &'static Regex { - SHORTCODE_RE.get_or_init(|| { - Regex::new( - r"https?://(?:www\.)?twitter\.com/([A-Za-z0-9_]+(?:/[A-Za-z0-9_]+)?)/status/(\d{1,20})", - ) - .expect("filed to compile regex") - }) -} +lazy_regex!( + URL_RE, + r#"https?://(?:www\.)?twitter\.com/([A-Za-z0-9_]+(?:/[A-Za-z0-9_]+)?)/status/(\d{1,20})"# +); /// Handler for Tiktok #[derive(Clone, Default)] @@ -39,7 +32,7 @@ impl SocialHandler for TwitterHandler { } fn try_extract(&self, text: &str) -> Option { - shortcode_regex() + regex() .captures(text) .and_then(|c| c.get(0).map(|m| m.as_str().to_owned())) } diff --git a/src/handlers/youtube.rs b/src/handlers/youtube.rs index c658947..d48b26f 100644 --- a/src/handlers/youtube.rs +++ b/src/handlers/youtube.rs @@ -1,21 +1,16 @@ use crate::handlers::SocialHandler; +use crate::lazy_regex; use crate::{ download::{download_ytdlp, process_download_result}, error::Result, }; -use regex::Regex; -use std::sync::OnceLock; use teloxide::{Bot, types::ChatId}; use tracing::info; -static SHORTCODE_RE: OnceLock = OnceLock::new(); - -fn shortcode_regex() -> &'static Regex { - SHORTCODE_RE.get_or_init(|| { - Regex::new(r"https?:\/\/(?:www\.)?youtube\.com\/shorts\/[A-Za-z0-9_-]+(?:\?[^\s]*)?") - .expect("filed to compile regex") - }) -} +lazy_regex!( + URL_RE, + r#"https?:\/\/(?:www\.)?youtube\.com\/shorts\/[A-Za-z0-9_-]+(?:\?[^\s]*)?"# +); /// Handler for `YouTube Shorts` (and short youtu.be links) #[derive(Clone, Default)] @@ -36,7 +31,7 @@ impl SocialHandler for YouTubeShortsHandler { } fn try_extract(&self, text: &str) -> Option { - shortcode_regex().find(text).map(|m| m.as_str().to_owned()) + regex().find(text).map(|m| m.as_str().to_owned()) } async fn handle(&self, bot: &Bot, chat_id: ChatId, url: String) -> Result<()> {