mirror of
https://github.com/kristoferssolo/tg-relay-rs.git
synced 2025-12-20 11:04:41 +00:00
chore: fix clippy warnings
This commit is contained in:
parent
17f29f59be
commit
3607d29887
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -123,6 +123,12 @@ version = "1.10.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "capitalize"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b5271031022835ee8c7582fe67403bd6cb3d962095787af7921027234bab5bf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.38"
|
version = "1.2.38"
|
||||||
@ -1726,6 +1732,7 @@ name = "tg-relay-rs"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"capitalize",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
|
|||||||
@ -7,6 +7,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
|
capitalize = "0.3.4"
|
||||||
color-eyre = "0.6"
|
color-eyre = "0.6"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
|||||||
@ -107,7 +107,7 @@ pub fn init_global_comments(comments: Comments) -> Result<()> {
|
|||||||
.map_err(|_| Error::other("comments already initialized"))
|
.map_err(|_| Error::other("comments already initialized"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get global comments (if initialized). Returns Option<&'static Comments>.
|
/// Get global comments (if initialized).
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn global_comments() -> Option<&'static Comments> {
|
pub fn global_comments() -> Option<&'static Comments> {
|
||||||
|
|||||||
@ -4,4 +4,3 @@ pub mod error;
|
|||||||
pub mod handlers;
|
pub mod handlers;
|
||||||
pub mod telemetry;
|
pub mod telemetry;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod validate;
|
|
||||||
|
|||||||
@ -8,5 +8,5 @@ pub fn setup_logger() {
|
|||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(env_filter)
|
.with(env_filter)
|
||||||
.with(formatter)
|
.with(formatter)
|
||||||
.init()
|
.init();
|
||||||
}
|
}
|
||||||
|
|||||||
71
src/utils.rs
71
src/utils.rs
@ -2,18 +2,15 @@ use crate::{
|
|||||||
comments::{Comments, global_comments},
|
comments::{Comments, global_comments},
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
};
|
};
|
||||||
|
use capitalize::Capitalize;
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
|
fmt::Display,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use teloxide::{
|
use teloxide::{prelude::*, types::InputFile};
|
||||||
Bot,
|
|
||||||
payloads::{SendPhotoSetters, SendVideoSetters},
|
|
||||||
prelude::Requester,
|
|
||||||
types::{ChatId, InputFile},
|
|
||||||
};
|
|
||||||
use tokio::{fs::File, io::AsyncReadExt};
|
use tokio::{fs::File, io::AsyncReadExt};
|
||||||
use tracing::warn;
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
pub const VIDEO_EXTSTENSIONS: &[&str] = &["mp4", "webm", "mov", "mkv", "avi", "m4v", "3gp"];
|
pub const VIDEO_EXTSTENSIONS: &[&str] = &["mp4", "webm", "mov", "mkv", "avi", "m4v", "3gp"];
|
||||||
pub const IMAGE_EXTSTENSIONS: &[&str] = &["jpg", "jpeg", "png", "webp", "gif", "bmp"];
|
pub const IMAGE_EXTSTENSIONS: &[&str] = &["jpg", "jpeg", "png", "webp", "gif", "bmp"];
|
||||||
@ -26,6 +23,18 @@ pub enum MediaKind {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MediaKind {
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub const fn to_str(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Video => "video",
|
||||||
|
Self::Image => "image",
|
||||||
|
Self::Unknown => "unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Detect media kind first by extension, then by content/magic (sync).
|
/// Detect media kind first by extension, then by content/magic (sync).
|
||||||
pub fn detect_media_kind(path: &Path) -> MediaKind {
|
pub fn detect_media_kind(path: &Path) -> MediaKind {
|
||||||
if let Some(ext) = path.extension().and_then(OsStr::to_str) {
|
if let Some(ext) = path.extension().and_then(OsStr::to_str) {
|
||||||
@ -93,7 +102,7 @@ pub async fn detect_media_kind_async(path: &Path) -> MediaKind {
|
|||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns an error if sending fails or the media kind is unknown.
|
/// Returns an `Error::UnknownMediaKind` if sending fails or the media kind is unknown.
|
||||||
pub async fn send_media_from_path(
|
pub async fn send_media_from_path(
|
||||||
bot: &Bot,
|
bot: &Bot,
|
||||||
chat_id: ChatId,
|
chat_id: ChatId,
|
||||||
@ -104,32 +113,46 @@ pub async fn send_media_from_path(
|
|||||||
.map(Comments::build_caption)
|
.map(Comments::build_caption)
|
||||||
.filter(|caption| !caption.is_empty());
|
.filter(|caption| !caption.is_empty());
|
||||||
|
|
||||||
|
let input = InputFile::file(path);
|
||||||
|
|
||||||
|
macro_rules! send_msg {
|
||||||
|
($request_expr:expr) => {{
|
||||||
|
let mut request = $request_expr;
|
||||||
|
if let Some(cap) = caption_opt {
|
||||||
|
request = request.caption(cap);
|
||||||
|
}
|
||||||
|
if let Ok(message) = request.await {
|
||||||
|
info!(message_id = message.id.to_string(), "{} sent", kind);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
MediaKind::Video => {
|
MediaKind::Video => send_msg!(bot.send_video(chat_id, input)),
|
||||||
let video = InputFile::file(path);
|
MediaKind::Image => send_msg!(bot.send_photo(chat_id, input)),
|
||||||
let mut req = bot.send_video(chat_id, video);
|
|
||||||
if let Some(c) = caption_opt {
|
|
||||||
req = req.caption(c);
|
|
||||||
}
|
|
||||||
req.await?;
|
|
||||||
}
|
|
||||||
MediaKind::Image => {
|
|
||||||
let photo = InputFile::file(path);
|
|
||||||
let mut req = bot.send_photo(chat_id, photo);
|
|
||||||
if let Some(c) = caption_opt {
|
|
||||||
req = req.caption(c);
|
|
||||||
}
|
|
||||||
req.await?;
|
|
||||||
}
|
|
||||||
MediaKind::Unknown => {
|
MediaKind::Unknown => {
|
||||||
bot.send_message(chat_id, "No supported media found")
|
bot.send_message(chat_id, "No supported media found")
|
||||||
.await?;
|
.await?;
|
||||||
|
error!("No supported media found");
|
||||||
return Err(Error::UnknownMediaKind);
|
return Err(Error::UnknownMediaKind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for MediaKind {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
self.to_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for MediaKind {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.capitalize())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
use crate::error::Result;
|
|
||||||
use regex::Regex;
|
|
||||||
use std::sync::OnceLock;
|
|
||||||
|
|
||||||
/// Trait for validating platform-specific identifiers (e.g., shortcodes, URLs)
|
|
||||||
/// extracted from user input.
|
|
||||||
///
|
|
||||||
/// Implementors should:
|
|
||||||
/// - Check format (e.g., length, characters).
|
|
||||||
/// - Canonicalize if needed (e.g., trim query params from a URL).
|
|
||||||
/// - Return `Ok(canonical_id)` on success or `Err(Error::Other(...))` on failure.
|
|
||||||
pub trait Validate {
|
|
||||||
/// Validate the input and return a canonicalized String (e.g., cleaned shortcode or URL).
|
|
||||||
fn validate(&self, input: &str) -> Result<String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper function to create a lazy static Regex (reused across impls).
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// If no pattern found
|
|
||||||
pub fn lazy_regex(pattern: &str) -> &'static Regex {
|
|
||||||
static RE: OnceLock<Regex> = OnceLock::new();
|
|
||||||
RE.get_or_init(|| Regex::new(pattern).expect("failed to compile validation regex"))
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user