#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
#![allow(clippy::multiple_crate_versions)]
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone)]
pub struct CopyProgress {
pub files_total: u64,
pub files_copied: u64,
pub current_file: Option<String>,
}
impl CopyProgress {
#[must_use]
pub const fn new(files_total: u64, files_copied: u64, current_file: Option<String>) -> Self {
Self {
files_total,
files_copied,
current_file,
}
}
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub fn percentage(&self) -> f64 {
if self.files_total == 0 {
100.0
} else {
(self.files_copied as f64 / self.files_total as f64) * 100.0
}
}
}
#[derive(Debug)]
pub struct ProgressTracker {
files_total: AtomicU64,
files_copied: AtomicU64,
}
impl ProgressTracker {
#[must_use]
pub fn new() -> Arc<Self> {
Arc::new(Self {
files_total: AtomicU64::new(0),
files_copied: AtomicU64::new(0),
})
}
pub fn set_total(&self, total: u64) {
self.files_total.store(total, Ordering::SeqCst);
}
pub fn increment_copied(&self) {
self.files_copied.fetch_add(1, Ordering::SeqCst);
}
#[must_use]
pub fn total(&self) -> u64 {
self.files_total.load(Ordering::SeqCst)
}
#[must_use]
pub fn copied(&self) -> u64 {
self.files_copied.load(Ordering::SeqCst)
}
#[must_use]
pub fn snapshot(&self, current_file: Option<String>) -> CopyProgress {
CopyProgress::new(self.total(), self.copied(), current_file)
}
}
impl Default for ProgressTracker {
fn default() -> Self {
Self {
files_total: AtomicU64::new(0),
files_copied: AtomicU64::new(0),
}
}
}