mirror of
https://github.com/nushell/nushell.git
synced 2024-12-22 07:02:19 +01:00
Filesize formatting (#456)
* configure the format of filesize * type-o * removed some comments * updated tests * accomodated filesize_metric better, added test
This commit is contained in:
parent
a8e5cb871e
commit
3dc19d4179
139
Cargo.lock
generated
139
Cargo.lock
generated
@ -103,6 +103,15 @@ version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
|
||||
dependencies = [
|
||||
"nodrop",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
@ -269,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"arrayvec 0.5.2",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
@ -306,6 +315,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byte-unit"
|
||||
version = "4.0.13"
|
||||
@ -548,6 +563,16 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "cstr_core"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "917ba9efe9e1e736671d5a03f006afc4e7e3f32503e2077e0bcaf519c0c8c1d3"
|
||||
dependencies = [
|
||||
"cty",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
@ -590,6 +615,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||
|
||||
[[package]]
|
||||
name = "dialoguer"
|
||||
version = "0.9.0"
|
||||
@ -1137,6 +1168,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -1455,6 +1495,12 @@ dependencies = [
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "1.2.4"
|
||||
@ -1631,8 +1677,10 @@ dependencies = [
|
||||
"indexmap",
|
||||
"miette",
|
||||
"nu-json",
|
||||
"num-format",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sys-locale",
|
||||
"thiserror",
|
||||
"typetag",
|
||||
]
|
||||
@ -1754,6 +1802,16 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-format"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.12",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
@ -2660,6 +2718,19 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-locale"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91f89ebb59fa30d4f65fafc2d68e94f6975256fd87e812dd99cb6e020c8563df"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cstr_core",
|
||||
"libc",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.20.5"
|
||||
@ -2967,7 +3038,7 @@ version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"arrayvec 0.5.2",
|
||||
"utf8parse",
|
||||
"vte_generate_state_changes",
|
||||
]
|
||||
@ -3003,6 +3074,70 @@ version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -17,6 +17,8 @@ im = "15.0.0"
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
nu-json = { path = "../nu-json" }
|
||||
typetag = "0.1.8"
|
||||
num-format = "0.4.0"
|
||||
sys-locale = "0.1.0"
|
||||
|
||||
[features]
|
||||
plugin = ["serde_json"]
|
||||
|
@ -14,6 +14,7 @@ pub struct Config {
|
||||
pub footer_mode: FooterMode,
|
||||
pub animate_prompt: bool,
|
||||
pub float_precision: i64,
|
||||
pub filesize_format: String,
|
||||
pub without_color: bool,
|
||||
}
|
||||
|
||||
@ -28,6 +29,7 @@ impl Default for Config {
|
||||
footer_mode: FooterMode::Never,
|
||||
animate_prompt: ANIMATE_PROMPT_DEFAULT,
|
||||
float_precision: 4,
|
||||
filesize_format: "auto".into(),
|
||||
without_color: false,
|
||||
}
|
||||
}
|
||||
@ -74,7 +76,7 @@ impl Value {
|
||||
config.use_grid_icons = value.as_bool()?;
|
||||
}
|
||||
"footer_mode" => {
|
||||
let val_str = value.as_string()?;
|
||||
let val_str = value.as_string()?.to_lowercase();
|
||||
config.footer_mode = match val_str.as_ref() {
|
||||
"auto" => FooterMode::Auto,
|
||||
"never" => FooterMode::Never,
|
||||
@ -94,6 +96,9 @@ impl Value {
|
||||
"without_color" => {
|
||||
config.without_color = value.as_bool()?;
|
||||
}
|
||||
"filesize_format" => {
|
||||
config.filesize_format = value.as_string()?.to_lowercase();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,16 @@ mod range;
|
||||
mod stream;
|
||||
mod unit;
|
||||
|
||||
use byte_unit::ByteUnit;
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
use chrono_humanize::HumanTime;
|
||||
pub use from_value::FromValue;
|
||||
use indexmap::map::IndexMap;
|
||||
use num_format::{Locale, ToFormattedString};
|
||||
pub use range::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use stream::*;
|
||||
use sys_locale::get_locale;
|
||||
pub use unit::*;
|
||||
|
||||
use std::collections::HashMap;
|
||||
@ -1474,16 +1477,114 @@ pub fn format_duration(duration: i64) -> String {
|
||||
}
|
||||
|
||||
fn format_filesize(num_bytes: i64, config: &Config) -> String {
|
||||
// Allow the user to specify how they want their numbers formatted
|
||||
let filesize_format_var = get_config_filesize_format(config);
|
||||
|
||||
let byte = byte_unit::Byte::from_bytes(num_bytes as u128);
|
||||
let adj_byte =
|
||||
if filesize_format_var.0 == byte_unit::ByteUnit::B && filesize_format_var.1 == "auto" {
|
||||
byte.get_appropriate_unit(!config.filesize_metric)
|
||||
} else {
|
||||
byte.get_adjusted_unit(filesize_format_var.0)
|
||||
};
|
||||
|
||||
if byte.get_bytes() == 0u128 {
|
||||
return "—".to_string();
|
||||
}
|
||||
match adj_byte.get_unit() {
|
||||
byte_unit::ByteUnit::B => {
|
||||
let locale_string = get_locale().unwrap_or_else(|| String::from("en-US"));
|
||||
// Since get_locale() and Locale::from_name() don't always return the same items
|
||||
// we need to try and parse it to match. For instance, a valid locale is de_DE
|
||||
// however Locale::from_name() wants only de so we split and parse it out.
|
||||
let locale_string = locale_string.replace("_", "-"); // en_AU -> en-AU
|
||||
let locale = match Locale::from_name(&locale_string) {
|
||||
Ok(loc) => loc,
|
||||
_ => {
|
||||
let all = num_format::Locale::available_names();
|
||||
let locale_prefix = &locale_string.split('-').collect::<Vec<&str>>();
|
||||
if all.contains(&locale_prefix[0]) {
|
||||
// eprintln!("Found alternate: {}", &locale_prefix[0]);
|
||||
Locale::from_name(locale_prefix[0]).unwrap_or(Locale::en)
|
||||
} else {
|
||||
// eprintln!("Unable to find matching locale. Defaulting to en-US");
|
||||
Locale::en
|
||||
}
|
||||
}
|
||||
};
|
||||
let locale_byte = adj_byte.get_value() as u64;
|
||||
let locale_byte_string = locale_byte.to_formatted_string(&locale);
|
||||
|
||||
let byte = byte.get_appropriate_unit(config.filesize_metric);
|
||||
|
||||
match byte.get_unit() {
|
||||
byte_unit::ByteUnit::B => format!("{} B ", byte.get_value()),
|
||||
_ => byte.format(1),
|
||||
if filesize_format_var.1 == "auto" {
|
||||
format!("{} B", locale_byte_string)
|
||||
} else {
|
||||
locale_byte_string
|
||||
}
|
||||
}
|
||||
_ => adj_byte.format(1),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_config_filesize_format(config: &Config) -> (ByteUnit, &str) {
|
||||
// We need to take into account config.filesize_metric so, if someone asks for KB
|
||||
// filesize_metric is true, return KiB
|
||||
let filesize_format = match config.filesize_format.as_str() {
|
||||
"b" => (byte_unit::ByteUnit::B, ""),
|
||||
"kb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::KiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::KB, "")
|
||||
}
|
||||
}
|
||||
"kib" => (byte_unit::ByteUnit::KiB, ""),
|
||||
"mb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::MiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::MB, "")
|
||||
}
|
||||
}
|
||||
"mib" => (byte_unit::ByteUnit::MiB, ""),
|
||||
"gb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::GiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::GB, "")
|
||||
}
|
||||
}
|
||||
"gib" => (byte_unit::ByteUnit::GiB, ""),
|
||||
"tb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::TiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::TB, "")
|
||||
}
|
||||
}
|
||||
"tib" => (byte_unit::ByteUnit::TiB, ""),
|
||||
"pb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::PiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::PB, "")
|
||||
}
|
||||
}
|
||||
"pib" => (byte_unit::ByteUnit::PiB, ""),
|
||||
"eb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::EiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::EB, "")
|
||||
}
|
||||
}
|
||||
"eib" => (byte_unit::ByteUnit::EiB, ""),
|
||||
"zb" => {
|
||||
if config.filesize_metric {
|
||||
(byte_unit::ByteUnit::ZiB, "")
|
||||
} else {
|
||||
(byte_unit::ByteUnit::ZB, "")
|
||||
}
|
||||
}
|
||||
"zib" => (byte_unit::ByteUnit::ZiB, ""),
|
||||
_ => (byte_unit::ByteUnit::B, "auto"),
|
||||
};
|
||||
|
||||
filesize_format
|
||||
}
|
||||
|
17
src/tests.rs
17
src/tests.rs
@ -1148,19 +1148,28 @@ fn multi_word_imports() -> TestResult {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_var_1() -> TestResult {
|
||||
fn config_filesize_format_with_metric_true() -> TestResult {
|
||||
// Note: this tests both the config variable and that it is properly captured into a block
|
||||
run_test(
|
||||
r#"let config = {"filesize_metric": $true }; do { 40kb | into string } "#,
|
||||
r#"let config = {"filesize_metric": $true "filesize_format": "kib" }; do { 40kb | into string } "#,
|
||||
"39.1 KiB",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_var_2() -> TestResult {
|
||||
fn config_filesize_format_with_metric_false_kib() -> TestResult {
|
||||
// Note: this tests both the config variable and that it is properly captured into a block
|
||||
run_test(
|
||||
r#"let config = {"filesize_metric": $false }; do { 40kb | into string } "#,
|
||||
r#"let config = {"filesize_metric": $false "filesize_format": "kib" }; do { 40kb | into string } "#,
|
||||
"39.1 KiB",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_filesize_format_with_metric_false_kb() -> TestResult {
|
||||
// Note: this tests both the config variable and that it is properly captured into a block
|
||||
run_test(
|
||||
r#"let config = {"filesize_metric": $false "filesize_format": "kb" }; do { 40kb | into string } "#,
|
||||
"40.0 KB",
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user