From 65c9aa6c5c404781f41cdd58b53ee6f77ec5ac56 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Mon, 21 Sep 2026 17:41:57 +0800 Subject: [PATCH] refactor(send): inline parse_media_url, drop photos_first's rebind parse_media_url had a single caller (input_file_for) and read better as the one expression it wrapped; photos_first rebound its argument only to gain mut. --- crates/xmedia-bot/src/send/input_media.rs | 7 ++----- crates/xmedia-bot/src/send/mod.rs | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/xmedia-bot/src/send/input_media.rs b/crates/xmedia-bot/src/send/input_media.rs index 59981ff..735e73f 100644 --- a/crates/xmedia-bot/src/send/input_media.rs +++ b/crates/xmedia-bot/src/send/input_media.rs @@ -7,10 +7,6 @@ use teloxide::types::{ InputFile, InputMedia, InputMediaAnimation, InputMediaPhoto, InputMediaVideo, ParseMode, }; -fn parse_media_url(s: &str) -> Result { - url::Url::parse(s).map_err(|e| format!("invalid media URL: {e}")) -} - pub(super) fn item_url(item: &MediaItemPayload) -> &str { match item { MediaItemPayload::Photo { media, .. } @@ -23,7 +19,8 @@ pub(super) fn item_url(item: &MediaItemPayload) -> &str { /// (e.g. a locally encoded ugoira MP4) is uploaded directly. pub(super) fn input_file_for(media: &str) -> Result { if media.starts_with("http://") || media.starts_with("https://") { - Ok(InputFile::url(parse_media_url(media)?)) + let url = url::Url::parse(media).map_err(|e| format!("invalid media URL: {e}"))?; + Ok(InputFile::url(url)) } else if !std::path::Path::new(media).exists() { // A retried task may reference a temp file the original send's // TempDir already cleaned up; fail fast and permanent instead of diff --git a/crates/xmedia-bot/src/send/mod.rs b/crates/xmedia-bot/src/send/mod.rs index 79fbf44..0fa2830 100644 --- a/crates/xmedia-bot/src/send/mod.rs +++ b/crates/xmedia-bot/src/send/mod.rs @@ -349,8 +349,7 @@ pub fn chunk_media_items(items: Vec) -> Vec> { /// mixed, the first item must be a photo (Telegram's sendMediaGroup rule). /// Stable sort keeps the source order within each kind; a lone animation is /// untouched (it takes the SendAnimation path before this runs). -pub fn photos_first(items: Vec) -> Vec { - let mut items = items; +pub fn photos_first(mut items: Vec) -> Vec { items.sort_by_key(|item| match item { MediaItemPayload::Photo { .. } => 0, MediaItemPayload::Video { .. } | MediaItemPayload::Animation { .. } => 1,