Skip to main content

radicle_cli/terminal/
upload_pack.rs

1use std::collections::BTreeSet;
2use std::time::Instant;
3
4use crate::terminal::format;
5use radicle::node::NodeId;
6
7/// Keeps track of upload-pack progress for displaying to the terminal.
8pub struct UploadPack {
9    /// Keep track of which remotes are being uploaded to, removing any that
10    /// have completed.
11    remotes: BTreeSet<NodeId>,
12    /// Keep track of how long we've been transmitting for to calculate
13    /// throughput.
14    timer: Instant,
15}
16
17impl Default for UploadPack {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23impl UploadPack {
24    /// Construct an empty set of spinners.
25    #[must_use]
26    pub fn new() -> Self {
27        Self {
28            remotes: BTreeSet::new(),
29            timer: Instant::now(),
30        }
31    }
32
33    /// Display the number of peers, the total transmitted bytes, and the
34    /// throughput.
35    pub fn transmitted(&mut self, remote: NodeId, transmitted: usize) -> String {
36        self.remotes.insert(remote);
37        let throughput = transmitted as f64 / self.timer.elapsed().as_secs_f64();
38        let throughput = format::bytes(throughput.floor() as usize);
39        let n = self.remotes.len();
40        let transmitted = format::bytes(transmitted);
41        format!("Uploading to {n} peer(s) ({transmitted} | {throughput:.2}/s)")
42    }
43
44    /// Display which remote has completed upload-pack and how many are
45    /// remaining.
46    pub fn done(&mut self, remote: &NodeId) -> String {
47        self.remotes.remove(remote);
48        let n = self.remotes.len();
49        format!("Uploaded to {remote}, {n} peer(s) remaining..")
50    }
51}