1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::{fmt, hash::Hasher};
use crate::{progress::Step, unit::display};
pub trait DisplayValue {
fn display_current_value(&self, w: &mut dyn fmt::Write, value: Step, _upper: Option<Step>) -> fmt::Result {
fmt::write(w, format_args!("{}", value))
}
fn separator(&self, w: &mut dyn fmt::Write, _value: Step, _upper: Option<Step>) -> fmt::Result {
w.write_str("/")
}
fn display_upper_bound(&self, w: &mut dyn fmt::Write, upper_bound: Step, _value: Step) -> fmt::Result {
fmt::write(w, format_args!("{}", upper_bound))
}
fn dyn_hash(&self, state: &mut dyn std::hash::Hasher);
fn display_unit(&self, w: &mut dyn fmt::Write, value: Step) -> fmt::Result;
fn display_percentage(&self, w: &mut dyn fmt::Write, percentage: f64) -> fmt::Result {
w.write_fmt(format_args!("[{}%]", percentage as usize))
}
fn display_throughput(&self, w: &mut dyn fmt::Write, throughput: &display::Throughput) -> fmt::Result {
let (fraction, unit) = self.fraction_and_time_unit(throughput.timespan);
w.write_char('|')?;
self.display_current_value(w, throughput.value_change_in_timespan, None)?;
w.write_char('/')?;
match fraction {
Some(fraction) => w.write_fmt(format_args!("{}", fraction)),
None => Ok(()),
}?;
w.write_fmt(format_args!("{}|", unit))
}
fn fraction_and_time_unit(&self, timespan: std::time::Duration) -> (Option<f64>, &'static str) {
fn skip_one(v: f64) -> Option<f64> {
if (v - 1.0).abs() < f64::EPSILON {
None
} else {
Some(v)
}
}
const HOUR_IN_SECS: u64 = 60 * 60;
let secs = timespan.as_secs();
let h = secs / HOUR_IN_SECS;
if h > 0 {
return (skip_one(secs as f64 / HOUR_IN_SECS as f64), "h");
}
const MINUTES_IN_SECS: u64 = 60;
let m = secs / MINUTES_IN_SECS;
if m > 0 {
return (skip_one(secs as f64 / MINUTES_IN_SECS as f64), "m");
}
if secs > 0 {
return (skip_one(secs as f64), "s");
}
(skip_one(timespan.as_millis() as f64), "ms")
}
}
impl DisplayValue for &'static str {
fn dyn_hash(&self, state: &mut dyn Hasher) {
state.write(self.as_bytes())
}
fn display_unit(&self, w: &mut dyn fmt::Write, _value: usize) -> fmt::Result {
w.write_fmt(format_args!("{}", self))
}
}