Skip to main content

yt_dlp/cache/
layer.rs

1//! Consolidated cache layer.
2//!
3//! `CacheLayer` bundles all three domain caches (videos, downloads, playlists)
4//! into a single struct so the `Downloader` only needs one `Option<Arc<CacheLayer>>`.
5
6use crate::cache::config::CacheConfig;
7use crate::cache::files::DownloadCache;
8use crate::cache::playlist::PlaylistCache;
9use crate::cache::video::VideoCache;
10use crate::error::Result;
11
12/// Consolidated cache layer combining video, download, and playlist caches.
13///
14/// Created from a `CacheConfig` and stored as `Option<Arc<CacheLayer>>` on the
15/// `Downloader`. Each sub-cache uses its own TTL from the config, falling back
16/// to its domain-specific default.
17#[derive(Debug)]
18pub struct CacheLayer {
19    /// Video metadata cache (tiered L1/L2).
20    pub videos: VideoCache,
21    /// Downloaded file metadata cache (tiered L1/L2).
22    pub downloads: DownloadCache,
23    /// Playlist metadata cache (tiered L1/L2).
24    pub playlists: PlaylistCache,
25}
26
27impl CacheLayer {
28    /// Build a `CacheLayer` from a `CacheConfig`.
29    ///
30    /// # Arguments
31    ///
32    /// * `config` - The cache configuration specifying directories, TTLs, and backend settings.
33    ///
34    /// # Returns
35    ///
36    /// A new `CacheLayer` with all three domain caches initialized.
37    ///
38    /// # Errors
39    ///
40    /// Returns an error if any backend initialization fails.
41    pub async fn from_config(config: &CacheConfig) -> Result<Self> {
42        tracing::debug!(config = %config, "⚙️ Building cache layer from config");
43
44        let videos = VideoCache::new(config, config.video_ttl).await?;
45        let downloads = DownloadCache::new(config, config.download_ttl).await?;
46        let playlists = PlaylistCache::new(config, config.playlist_ttl).await?;
47
48        tracing::debug!("✅ Cache layer initialized");
49
50        Ok(Self {
51            videos,
52            downloads,
53            playlists,
54        })
55    }
56
57    /// Clean expired entries across all caches.
58    ///
59    /// # Errors
60    ///
61    /// Returns an error if cleanup fails for any sub-cache.
62    pub async fn clean(&self) -> Result<()> {
63        tracing::debug!("⚙️ Cleaning all caches");
64
65        self.videos.clean().await?;
66        self.downloads.clean().await?;
67        self.playlists.clean().await?;
68
69        Ok(())
70    }
71}