refactor(handlers): make lazy_regex macro

This commit is contained in:
Kristofers Solo 2025-10-27 11:51:15 +02:00
parent 89dec3387b
commit 90805674c6
Signed by: kristoferssolo
GPG Key ID: 74FF8144483D82C8
5 changed files with 35 additions and 48 deletions

View File

@ -1,21 +1,14 @@
use crate::download::{download_instagram, process_download_result}; use crate::download::{download_instagram, process_download_result};
use crate::error::Result; use crate::error::Result;
use crate::handlers::SocialHandler; use crate::handlers::SocialHandler;
use regex::Regex; use crate::lazy_regex;
use std::sync::OnceLock;
use teloxide::{Bot, types::ChatId}; use teloxide::{Bot, types::ChatId};
use tracing::info; use tracing::info;
static SHORTCODE_RE: OnceLock<Regex> = OnceLock::new(); lazy_regex!(
URL_RE,
fn shortcode_regex() -> &'static Regex { r#"https?://(?:www\.)?(?:instagram\.com|instagr\.am)/(?:p|reel|tv)/([A-Za-z0-9_-]+)"#
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")
})
}
/// Handler for Instagram posts / reels / tv /// Handler for Instagram posts / reels / tv
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -36,7 +29,7 @@ impl SocialHandler for InstagramHandler {
} }
fn try_extract(&self, text: &str) -> Option<String> { fn try_extract(&self, text: &str) -> Option<String> {
shortcode_regex() regex()
.captures(text) .captures(text)
.and_then(|c| c.get(0).map(|m| m.as_str().to_owned())) .and_then(|c| c.get(0).map(|m| m.as_str().to_owned()))
} }

View File

@ -19,6 +19,17 @@ pub use twitter::TwitterHandler;
#[cfg(feature = "youtube")] #[cfg(feature = "youtube")]
pub use youtube::YouTubeShortsHandler; pub use youtube::YouTubeShortsHandler;
#[macro_export]
macro_rules! lazy_regex {
($name:ident, $pattern:expr) => {
static $name: std::sync::OnceLock<regex::Regex> = 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] #[async_trait::async_trait]
pub trait SocialHandler: Send + Sync { pub trait SocialHandler: Send + Sync {
/// Short name used for logging etc. /// Short name used for logging etc.

View File

@ -1,22 +1,17 @@
use crate::{ use crate::{
download::{download_tiktok, process_download_result}, download::{download_tiktok, process_download_result},
error::Result, error::Result,
lazy_regex,
}; };
use regex::Regex;
use std::sync::OnceLock;
use teloxide::{Bot, types::ChatId}; use teloxide::{Bot, types::ChatId};
use tracing::info; use tracing::info;
use crate::handlers::SocialHandler; use crate::handlers::SocialHandler;
static SHORTCODE_RE: OnceLock<Regex> = OnceLock::new(); lazy_regex!(
URL_RE,
fn shortcode_regex() -> &'static Regex { r#"https?://(?:www\.)?(?:vm|vt|tt|tik)\.tiktok\.com/([A-Za-z0-9_-]+)[/?#]?"#
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")
})
}
/// Handler for Tiktok /// Handler for Tiktok
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -37,7 +32,7 @@ impl SocialHandler for TiktokHandler {
} }
fn try_extract(&self, text: &str) -> Option<String> { fn try_extract(&self, text: &str) -> Option<String> {
shortcode_regex() regex()
.captures(text) .captures(text)
.and_then(|c| c.get(0).map(|m| m.as_str().to_owned())) .and_then(|c| c.get(0).map(|m| m.as_str().to_owned()))
} }

View File

@ -1,24 +1,17 @@
use crate::{ use crate::{
download::{download_twitter, process_download_result}, download::{download_twitter, process_download_result},
error::Result, error::Result,
lazy_regex,
}; };
use regex::Regex;
use std::sync::OnceLock;
use teloxide::{Bot, types::ChatId}; use teloxide::{Bot, types::ChatId};
use tracing::info; use tracing::info;
use crate::handlers::SocialHandler; use crate::handlers::SocialHandler;
static SHORTCODE_RE: OnceLock<Regex> = OnceLock::new(); lazy_regex!(
URL_RE,
fn shortcode_regex() -> &'static Regex { r#"https?://(?:www\.)?twitter\.com/([A-Za-z0-9_]+(?:/[A-Za-z0-9_]+)?)/status/(\d{1,20})"#
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")
})
}
/// Handler for Tiktok /// Handler for Tiktok
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -39,7 +32,7 @@ impl SocialHandler for TwitterHandler {
} }
fn try_extract(&self, text: &str) -> Option<String> { fn try_extract(&self, text: &str) -> Option<String> {
shortcode_regex() regex()
.captures(text) .captures(text)
.and_then(|c| c.get(0).map(|m| m.as_str().to_owned())) .and_then(|c| c.get(0).map(|m| m.as_str().to_owned()))
} }

View File

@ -1,21 +1,16 @@
use crate::handlers::SocialHandler; use crate::handlers::SocialHandler;
use crate::lazy_regex;
use crate::{ use crate::{
download::{download_ytdlp, process_download_result}, download::{download_ytdlp, process_download_result},
error::Result, error::Result,
}; };
use regex::Regex;
use std::sync::OnceLock;
use teloxide::{Bot, types::ChatId}; use teloxide::{Bot, types::ChatId};
use tracing::info; use tracing::info;
static SHORTCODE_RE: OnceLock<Regex> = OnceLock::new(); lazy_regex!(
URL_RE,
fn shortcode_regex() -> &'static Regex { r#"https?:\/\/(?:www\.)?youtube\.com\/shorts\/[A-Za-z0-9_-]+(?:\?[^\s]*)?"#
SHORTCODE_RE.get_or_init(|| { );
Regex::new(r"https?:\/\/(?:www\.)?youtube\.com\/shorts\/[A-Za-z0-9_-]+(?:\?[^\s]*)?")
.expect("filed to compile regex")
})
}
/// Handler for `YouTube Shorts` (and short youtu.be links) /// Handler for `YouTube Shorts` (and short youtu.be links)
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -36,7 +31,7 @@ impl SocialHandler for YouTubeShortsHandler {
} }
fn try_extract(&self, text: &str) -> Option<String> { fn try_extract(&self, text: &str) -> Option<String> {
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<()> { async fn handle(&self, bot: &Bot, chat_id: ChatId, url: String) -> Result<()> {