gglib_core/ports/
download_state.rs

1//! Download state repository port definition.
2//!
3//! This port defines the interface for persisting download queue state.
4//! Implementations handle durable storage of queued downloads so they
5//! survive application restarts.
6//!
7//! # Design
8//!
9//! - Persists queue state and terminal results only
10//! - Fine-grained progress stays in-memory (high churn, not worth persisting)
11//! - Intent-based methods, not generic CRUD
12
13use async_trait::async_trait;
14
15use super::RepositoryError;
16use crate::download::{DownloadId, DownloadStatus, QueuedDownload};
17
18/// Port for persisting download queue state.
19///
20/// This trait is implemented by `gglib-db` and injected into the download
21/// manager to provide durable queue storage.
22///
23/// # Persistence Scope
24///
25/// **Persisted:**
26/// - Queued downloads (survive restarts)
27/// - Terminal results (completed/failed with enough info for history)
28/// - Retry counts (if retries are supported)
29///
30/// **In-memory only:**
31/// - Fine-grained progress (bytes, speed)
32/// - Active progress snapshots (broadcast via events)
33///
34/// # Usage
35///
36/// ```ignore
37/// let repo: Arc<dyn DownloadStateRepositoryPort> = /* ... */;
38/// repo.enqueue(&queued_download).await?;
39/// let queue = repo.load_queue().await?;
40/// ```
41#[async_trait]
42pub trait DownloadStateRepositoryPort: Send + Sync {
43    /// Add a download to the persistent queue.
44    ///
45    /// The download should be in `Queued` status when enqueued.
46    async fn enqueue(&self, download: &QueuedDownload) -> Result<(), RepositoryError>;
47
48    /// Update the status of an existing download.
49    ///
50    /// This is used to transition downloads through their lifecycle:
51    /// Queued -> Downloading -> Completed/Failed/Cancelled
52    async fn update_status(
53        &self,
54        id: &DownloadId,
55        status: DownloadStatus,
56    ) -> Result<(), RepositoryError>;
57
58    /// Load all queued downloads from persistent storage.
59    ///
60    /// Returns downloads that were queued but not yet completed.
61    /// Used on application startup to restore the queue.
62    async fn load_queue(&self) -> Result<Vec<QueuedDownload>, RepositoryError>;
63
64    /// Mark a download as failed with an error message.
65    ///
66    /// This records the failure for history/retry purposes.
67    async fn mark_failed(
68        &self,
69        id: &DownloadId,
70        error_message: &str,
71    ) -> Result<(), RepositoryError>;
72
73    /// Remove a download from the persistent queue.
74    ///
75    /// Used when a download is cancelled or cleaned up.
76    async fn remove(&self, id: &DownloadId) -> Result<(), RepositoryError>;
77
78    /// Prune completed/failed downloads older than the given age.
79    ///
80    /// This is optional cleanup to prevent unbounded growth.
81    async fn prune_completed(&self, older_than_days: u32) -> Result<u32, RepositoryError>;
82}