use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use crate::download::types::ProgressCallback;
pub struct SegmentContext {
pub file: Arc<std::fs::File>,
pub downloaded_bytes: Arc<AtomicU64>,
pub progress_callback: Option<ProgressCallback>,
pub total_bytes: u64,
pub file_offset_base: u64,
pub is_resuming: bool,
}
impl std::fmt::Debug for SegmentContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SegmentContext")
.field("downloaded_bytes", &self.downloaded_bytes.load(Ordering::Relaxed))
.field("total_bytes", &self.total_bytes)
.field("has_callback", &self.progress_callback.is_some())
.finish()
}
}
impl std::fmt::Display for SegmentContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"SegmentContext(downloaded={}, total={})",
self.downloaded_bytes.load(Ordering::Relaxed),
self.total_bytes
)
}
}
impl SegmentContext {
pub fn new(file: Arc<std::fs::File>, total_bytes: u64, progress_callback: Option<ProgressCallback>) -> Self {
tracing::debug!(
total_bytes = total_bytes,
has_callback = progress_callback.is_some(),
"⚙️ Created new segment context"
);
Self {
file,
downloaded_bytes: Arc::new(AtomicU64::new(0)),
progress_callback,
total_bytes,
file_offset_base: 0,
is_resuming: false,
}
}
pub fn update_progress(&self, bytes: u64) {
let downloaded = self.downloaded_bytes.fetch_add(bytes, Ordering::Relaxed);
let new_total = downloaded + bytes;
let percentage = (new_total as f64 / self.total_bytes as f64) * 100.0;
tracing::debug!(
bytes_downloaded = bytes,
total_downloaded = new_total,
total_bytes = self.total_bytes,
percentage = percentage,
"📥 Segment progress updated"
);
if let Some(callback) = &self.progress_callback {
callback(new_total, self.total_bytes);
}
}
}