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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use std::{fmt, ops::Deref, sync::Arc};
use crate::progress::Step;
#[cfg(feature = "unit-bytes")]
mod bytes;
#[cfg(feature = "unit-bytes")]
pub use bytes::Bytes;
#[cfg(feature = "unit-duration")]
mod duration;
#[cfg(feature = "unit-duration")]
pub use duration::Duration;
#[cfg(feature = "unit-human")]
pub mod human;
#[cfg(feature = "unit-human")]
#[doc(inline)]
pub use human::Human;
mod range;
pub use range::Range;
mod traits;
pub use traits::DisplayValue;
pub mod display;
#[derive(Debug, Clone, Hash)]
pub struct Unit {
kind: Kind,
mode: Option<display::Mode>,
}
#[derive(Clone)]
pub enum Kind {
Label(&'static str),
Dynamic(Arc<dyn DisplayValue + Send + Sync>),
}
impl std::hash::Hash for Kind {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Kind::Label(s) => {
0.hash(state);
s.dyn_hash(state)
}
Kind::Dynamic(label) => {
1.hash(state);
label.dyn_hash(state);
}
}
}
}
impl fmt::Debug for Kind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Kind::Label(name) => f.write_fmt(format_args!("Unit::Label({:?})", name)),
Kind::Dynamic(_) => f.write_fmt(format_args!("Unit::Dynamic(..)")),
}
}
}
impl From<&'static str> for Unit {
fn from(v: &'static str) -> Self {
label(v)
}
}
pub fn label(label: &'static str) -> Unit {
Unit {
kind: Kind::Label(label),
mode: None,
}
}
pub fn label_and_mode(label: &'static str, mode: display::Mode) -> Unit {
Unit {
kind: Kind::Label(label),
mode: Some(mode),
}
}
pub fn dynamic(label: impl DisplayValue + Send + Sync + 'static) -> Unit {
Unit {
kind: Kind::Dynamic(Arc::new(label)),
mode: None,
}
}
pub fn dynamic_and_mode(label: impl DisplayValue + Send + Sync + 'static, mode: display::Mode) -> Unit {
Unit {
kind: Kind::Dynamic(Arc::new(label)),
mode: Some(mode),
}
}
impl Unit {
pub fn display(
&self,
current_value: Step,
upper_bound: Option<Step>,
throughput: impl Into<Option<display::Throughput>>,
) -> display::UnitDisplay {
display::UnitDisplay {
current_value,
upper_bound,
throughput: throughput.into(),
parent: self,
display: display::What::ValuesAndUnit,
}
}
pub fn as_display_value(&self) -> &dyn DisplayValue {
match self.kind {
Kind::Label(ref unit) => unit,
Kind::Dynamic(ref unit) => unit.deref(),
}
}
}