use tokio::sync::mpsc;
const PROGRESS_CHANNEL_CAPACITY: usize = 8;
#[derive(Clone)]
pub struct ProgressSender {
tx: mpsc::Sender<ProgressUpdate>,
total: usize,
}
#[derive(Debug, Clone, Copy)]
pub struct ProgressUpdate {
pub fetched: usize,
pub total: usize,
}
impl ProgressSender {
pub fn send(&self, fetched: usize) {
let _ = self.tx.try_send(ProgressUpdate {
fetched,
total: self.total,
});
}
}
#[must_use]
pub fn channel(total: usize) -> (ProgressSender, mpsc::Receiver<ProgressUpdate>) {
let (tx, rx) = mpsc::channel(PROGRESS_CHANNEL_CAPACITY);
(ProgressSender { tx, total }, rx)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_percentage_calculation() {
let calculate = |fetched: usize, total: usize| -> u32 {
if total == 0 {
return 0;
}
((fetched as f64 / total as f64) * 100.0) as u32
};
assert_eq!(calculate(0, 10), 0);
assert_eq!(calculate(5, 10), 50);
assert_eq!(calculate(10, 10), 100);
assert_eq!(calculate(7, 10), 70);
assert_eq!(calculate(0, 0), 0);
}
#[tokio::test]
async fn test_progress_sender_try_send_on_closed_channel() {
let (sender, rx) = channel(10);
drop(rx);
sender.send(5);
}
#[tokio::test]
async fn test_progress_sender_try_send_on_full_channel() {
let (tx, _rx) = mpsc::channel(1);
let sender = ProgressSender { tx, total: 10 };
sender.send(1);
sender.send(2);
sender.send(3);
}
}