Skip to content

Commit 94c3195

Browse files
committed
feat: always show units and add display impl
1 parent ffabef5 commit 94c3195

File tree

1 file changed

+65
-27
lines changed

1 file changed

+65
-27
lines changed

src/app/data_display_options.rs

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use std::collections::{BTreeMap, BTreeSet};
2-
3-
use egui::Color32;
1+
use egui::{Color32, WidgetText};
2+
use std::{
3+
collections::{BTreeMap, BTreeSet},
4+
fmt::Display,
5+
};
46

57
#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq)]
68
#[serde(default)] // if we add new fields, give them default values when deserializing old state
@@ -65,48 +67,72 @@ pub struct RowSizeConfig {
6567
pub units: SizeUnits,
6668
}
6769

68-
#[derive(Default, serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq)]
70+
#[derive(Default, serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone, Copy)]
6971
pub enum SizeUnits {
7072
Bytes,
7173
KB,
7274
MB,
7375
GB,
7476
TB,
7577
#[default]
76-
/// Is output as a String because it includes the unit and is the largest unit where the output value is >= 1
7778
Auto,
7879
}
80+
7981
impl SizeUnits {
80-
pub(crate) fn convert(&self, row_size_in_bytes: usize) -> serde_json::Value {
81-
let scalar = match self {
82+
fn to_concrete(self, row_size_in_bytes: usize) -> Self {
83+
if !matches!(self, Self::Auto) {
84+
// Easy case where type is specified
85+
return self;
86+
}
87+
88+
// Determine which unit to use when using auto
89+
let units = [Self::Bytes, Self::KB, Self::MB, Self::GB, Self::TB];
90+
let mut last_index = 0;
91+
let row_size_in_bytes = row_size_in_bytes as f64;
92+
for (i, unit) in units.iter().enumerate().skip(1) {
93+
if (row_size_in_bytes / unit.scalar()) >= 1.0 {
94+
last_index = i;
95+
} else {
96+
// Last was as correct unit
97+
break;
98+
}
99+
}
100+
units[last_index]
101+
}
102+
103+
/// Returns the scalar for that unit
104+
///
105+
/// Panics: if unit is [`Self::Auto`]
106+
fn scalar(&self) -> f64 {
107+
match self {
82108
SizeUnits::Bytes => 1.0,
83109
SizeUnits::KB => 1024.0,
84110
SizeUnits::MB => 1024.0 * 1024.0,
85111
SizeUnits::GB => 1024.0 * 1024.0 * 1024.0,
86112
SizeUnits::TB => 1024.0 * 1024.0 * 1024.0 * 1024.0,
87113
SizeUnits::Auto => {
88-
// TODO 5: Rewrite with shifts for performance
89-
// Special handling see doc string for explanation
90-
let units = ["Bytes", "KB", "MB", "GB", "TB"];
91-
let mut last_index = 0;
92-
let mut scalar = 1.0f64;
93-
let row_size_in_bytes = row_size_in_bytes as f64;
94-
for i in 1..units.len() {
95-
let new_scalar = scalar * 1024.0;
96-
if (row_size_in_bytes / new_scalar) >= 1.0 {
97-
last_index = i;
98-
scalar = new_scalar;
99-
} else {
100-
// Last was as correct unit
101-
break;
102-
}
103-
}
104-
let result = row_size_in_bytes / scalar;
105-
return format!("{result:0>9.4} {}", units[last_index]).into();
114+
unreachable!("precondition violated: Auto does not have a scalar")
106115
}
107-
};
116+
}
117+
}
118+
119+
/// Output as a string because includes the unit
120+
pub(crate) fn convert(&self, row_size_in_bytes: usize) -> serde_json::Value {
121+
let concrete_unit = self.to_concrete(row_size_in_bytes);
122+
let scalar = concrete_unit.scalar();
108123
let result = row_size_in_bytes as f64 / scalar;
109-
result.into()
124+
format!("{result:0>9.4} {concrete_unit}").into()
125+
}
126+
127+
pub fn as_str(&self) -> &'static str {
128+
match self {
129+
SizeUnits::Bytes => "Bytes",
130+
SizeUnits::KB => "KB",
131+
SizeUnits::MB => "MB",
132+
SizeUnits::GB => "GB",
133+
SizeUnits::TB => "TB",
134+
SizeUnits::Auto => "Auto",
135+
}
110136
}
111137
}
112138

@@ -222,3 +248,15 @@ impl Default for LevelConversion {
222248
}
223249
}
224250
}
251+
252+
impl Display for SizeUnits {
253+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254+
write!(f, "{}", self.as_str())
255+
}
256+
}
257+
258+
impl From<SizeUnits> for WidgetText {
259+
fn from(value: SizeUnits) -> Self {
260+
value.as_str().into()
261+
}
262+
}

0 commit comments

Comments
 (0)