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    pub fn new() -> Self {
26        Self {
27            remotes: BTreeSet::new(),
28            timer: Instant::now(),
29        }
30    }
31
32    /// Display the number of peers, the total transmitted bytes, and the
33    /// throughput.
34    pub fn transmitted(&mut self, remote: NodeId, transmitted: usize) -> String {
35        self.remotes.insert(remote);
36        let throughput = transmitted as f64 / self.timer.elapsed().as_secs_f64();
37        let throughput = format::bytes(throughput.floor() as usize);
38        let n = self.remotes.len();
39        let transmitted = format::bytes(transmitted);
40        format!("Uploading to {n} peer(s) ({transmitted} | {throughput:.2}/s)")
41    }
42
43    /// Display which remote has completed upload-pack and how many are
44    /// remaining.
45    pub fn done(&mut self, remote: &NodeId) -> String {
46        self.remotes.remove(remote);
47        let n = self.remotes.len();
48        format!("Uploaded to {remote}, {n} peer(s) remaining..")
49    }
50}