Compare commits

..

1 Commits

Author SHA1 Message Date
andy.boot 37a488ed78 refactor: minimum-size & output-format
share code for handling kb/kib/mb/mib logic
2024-03-14 20:15:53 +00:00
2 changed files with 44 additions and 41 deletions
+17 -31
View File
@@ -6,7 +6,7 @@ use std::io::IsTerminal;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use crate::display::UNITS; use crate::display::get_number_format;
#[derive(Deserialize, Default)] #[derive(Deserialize, Default)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
@@ -116,44 +116,30 @@ impl Config {
} }
fn convert_min_size(input: &str) -> Option<usize> { fn convert_min_size(input: &str) -> Option<usize> {
// let chars_as_vec: Vec<char> = input.chars().collect();
let re = Regex::new(r"([0-9]+)(\w*)").unwrap(); let re = Regex::new(r"([0-9]+)(\w*)").unwrap();
if let Some(cap) = re.captures(input) { if let Some(cap) = re.captures(input) {
let (_, [digits, letters]) = cap.extract(); let (_, [digits, letters]) = cap.extract();
let letters = letters.to_uppercase();
let first = letters.chars().next();
// If we did specify a letter and it doesnt begin with 'b' // Failure to parse should be impossible due to regex match
if first.is_some() && first != Some('b') { let digits_as_usize: Option<usize> = digits.parse().ok();
// Are we using KB, MB, GB etc ?
for (i, u) in UNITS.iter().rev().enumerate() {
if Some(*u) == first {
return match digits.parse::<usize>() {
Ok(pure) => {
let is_si = letters.contains('I'); // KiB, MiB, etc
let num: usize = if is_si { 1000 } else { 1024 };
let marker = pure * (num.pow((i + 1) as u32)); match digits_as_usize {
Some(marker) Some(parsed_digits) => {
} let number_format = get_number_format(&letters.to_lowercase());
Err(_) => { match number_format {
eprintln!("Ignoring invalid min-size: {input}"); Some((multiple, _)) => Some(parsed_digits * (multiple as usize)),
None None => {
} if letters.eq("") {
}; Some(parsed_digits)
}
}
eprintln!("Ignoring invalid min-size: {input}");
None
// Else we are working with bytes
} else { } else {
digits
.parse()
.map_err(|_| {
eprintln!("Ignoring invalid min-size: {input}"); eprintln!("Ignoring invalid min-size: {input}");
}) None
.ok() }
}
}
}
None => None,
} }
} else { } else {
None None
+23 -6
View File
@@ -409,22 +409,37 @@ fn get_pretty_name(
} }
} }
pub fn human_readable_number(size: u64, output_str: &str) -> String { // If we are working with SI units or not
pub fn get_type_of_thousand(output_str: &str) -> u64 {
let is_si = output_str.contains('i'); // si, KiB, MiB, etc let is_si = output_str.contains('i'); // si, KiB, MiB, etc
let num: u64 = if is_si { 1000 } else { 1024 }; if is_si {
1000
} else {
1024
}
}
pub fn get_number_format(output_str: &str) -> Option<(u64, char)> {
if output_str.starts_with('b') { if output_str.starts_with('b') {
return format!("{}B", size); return Some((1, 'B'));
} }
for (i, u) in UNITS.iter().enumerate() { for (i, u) in UNITS.iter().enumerate() {
if output_str.starts_with((*u).to_ascii_lowercase()) { if output_str.starts_with((*u).to_ascii_lowercase()) {
let marker = num.pow((UNITS.len() - i) as u32); let marker = get_type_of_thousand(output_str).pow((UNITS.len() - i) as u32);
return format!("{}{}", (size / marker), u); return Some((marker, *u));
} }
} }
None
}
pub fn human_readable_number(size: u64, output_str: &str) -> String {
match get_number_format(output_str) {
Some((x, u)) => {
format!("{}{}", (size / x), u)
}
None => {
for (i, u) in UNITS.iter().enumerate() { for (i, u) in UNITS.iter().enumerate() {
let marker = num.pow((UNITS.len() - i) as u32); let marker = get_type_of_thousand(output_str).pow((UNITS.len() - i) as u32);
if size >= marker { if size >= marker {
if size / marker < 10 { if size / marker < 10 {
return format!("{:.1}{}", (size as f32 / marker as f32), u); return format!("{:.1}{}", (size as f32 / marker as f32), u);
@@ -434,6 +449,8 @@ pub fn human_readable_number(size: u64, output_str: &str) -> String {
} }
} }
format!("{size}B") format!("{size}B")
}
}
} }
mod tests { mod tests {