Skip to main content

yt_dlp/utils/
mod.rs

1//! Utility functions and types used throughout the application.
2//!
3//! This module contains various utilities for file system operations,
4//! HTTP connections, retry logic, and validation.
5
6use std::time::{SystemTime, UNIX_EPOCH};
7
8use tokio::task::JoinHandle;
9
10use crate::error::Result;
11
12pub mod fs;
13pub mod http;
14pub mod network;
15pub mod platform;
16pub mod subtitle;
17pub mod validation;
18
19// Re-export for backward compatibility
20// Re-export commonly used functions from fs
21pub use fs::*;
22pub use network::{retry, url_expiry};
23pub use platform::Platform;
24pub use subtitle::subtitle_converter::convert_subtitle;
25pub use subtitle::subtitle_validator::{ValidationResult, is_format_compatible, validate_subtitle};
26pub use url_expiry::{ExpiryConfig, UrlStatus, check_download_error, should_refresh_url};
27
28/// Converts a vector of string slices to a vector of owned strings.
29///
30/// # Arguments
31///
32/// * `vec` - The vector of string references to convert
33///
34/// # Returns
35///
36/// A vector of owned strings
37pub fn to_owned(vec: Vec<impl AsRef<str>>) -> Vec<String> {
38    vec.into_iter().map(|s| s.as_ref().to_owned()).collect()
39}
40
41/// Find the name of the executable for the given platform.
42///
43/// # Arguments
44///
45/// * `name` - The base name of the executable
46///
47/// # Returns
48///
49/// The platform-specific executable name (with .exe extension on Windows)
50pub fn find_executable(name: impl AsRef<str>) -> String {
51    let platform = Platform::detect();
52    let name_str = name.as_ref();
53
54    match platform {
55        Platform::Windows => format!("{}.exe", name_str),
56        _ => name_str.to_string(),
57    }
58}
59
60/// Awaits two futures and returns a tuple of their results.
61/// If either future returns an error, the error is propagated.
62///
63/// # Arguments
64///
65/// * `first` - The first future to await.
66/// * `second` - The second future to await.
67pub async fn await_two<T: std::fmt::Debug>(
68    first: JoinHandle<Result<T>>,
69    second: JoinHandle<Result<T>>,
70) -> Result<(T, T)> {
71    tracing::debug!("⚙️ Awaiting two futures");
72
73    let (first_result, second_result) = tokio::try_join!(first, second)?;
74
75    let first = first_result?;
76    let second = second_result?;
77
78    tracing::debug!("✅ Both futures completed successfully");
79
80    Ok((first, second))
81}
82
83/// Awaits all futures and returns a vector of their results.
84/// If any future returns an error, the error is propagated.
85///
86/// # Arguments
87///
88/// * `handles` - The futures to await
89///
90/// # Returns
91///
92/// A vector containing all the results
93///
94/// # Errors
95///
96/// Returns an error if any future fails
97pub async fn await_all<T, I>(handles: I) -> Result<Vec<T>>
98where
99    I: IntoIterator<Item = JoinHandle<Result<T>>> + std::fmt::Debug,
100    T: Send + 'static,
101{
102    tracing::debug!("⚙️ Awaiting multiple futures");
103
104    let results = futures_util::future::try_join_all(handles).await?;
105
106    let result_vec: Result<Vec<T>> = results.into_iter().collect();
107
108    if let Ok(ref vec) = result_vec {
109        tracing::debug!(completed_count = vec.len(), "✅ All futures completed successfully");
110    }
111
112    result_vec
113}
114
115/// Returns the current timestamp in seconds since UNIX epoch.
116///
117/// # Returns
118///
119/// Unix timestamp in seconds as i64.
120pub fn current_timestamp() -> i64 {
121    SystemTime::now()
122        .duration_since(UNIX_EPOCH)
123        .unwrap_or_default()
124        .as_secs() as i64
125}
126
127/// Checks if a timestamp is expired given a TTL.
128///
129/// # Arguments
130///
131/// * `cached_at` - The timestamp when the item was cached (Unix timestamp in seconds)
132/// * `ttl` - Time-to-live in seconds
133///
134/// # Returns
135///
136/// `true` if the cached item has expired, `false` otherwise.
137pub fn is_expired(cached_at: i64, ttl: u64) -> bool {
138    let now = current_timestamp();
139    (now - cached_at) > ttl as i64
140}