mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
Move filesize to use bigint (#2984)
* Move filesize to be bigint-sized * Add tests and fix filesize display * clippy
This commit is contained in:
parent
7b4cbd7ce9
commit
44e088c6fe
17 changed files with 227 additions and 148 deletions
|
@ -173,6 +173,13 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
|
||||||
let output = format_leaf(&x).plain_string(100_000);
|
let output = format_leaf(&x).plain_string(100_000);
|
||||||
out!("{}", output);
|
out!("{}", output);
|
||||||
}
|
}
|
||||||
|
Value {
|
||||||
|
value: UntaggedValue::Primitive(Primitive::Filesize(_)),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let output = format_leaf(&x).plain_string(100_000);
|
||||||
|
out!("{}", output);
|
||||||
|
}
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::Date(d)),
|
value: UntaggedValue::Primitive(Primitive::Date(d)),
|
||||||
..
|
..
|
||||||
|
|
|
@ -108,60 +108,70 @@ fn convert_bytes_to_string_using_format(
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
match bytes.value {
|
match bytes.value {
|
||||||
Primitive(Filesize(b)) => {
|
Primitive(Filesize(b)) => {
|
||||||
let byte = byte_unit::Byte::from_bytes(b as u128);
|
if let Some(value) = b.to_u128() {
|
||||||
let value = match format.item().to_lowercase().as_str() {
|
let byte = byte_unit::Byte::from_bytes(value);
|
||||||
"b" => Ok(UntaggedValue::string(b.to_formatted_string(&Locale::en))),
|
let value = match format.item().to_lowercase().as_str() {
|
||||||
"kb" => Ok(UntaggedValue::string(
|
"b" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::KB).to_string(),
|
value.to_formatted_string(&Locale::en),
|
||||||
)),
|
)),
|
||||||
"kib" => Ok(UntaggedValue::string(
|
"kb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::KiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::KB).to_string(),
|
||||||
)),
|
)),
|
||||||
"mb" => Ok(UntaggedValue::string(
|
"kib" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::MB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::KiB).to_string(),
|
||||||
)),
|
)),
|
||||||
"mib" => Ok(UntaggedValue::string(
|
"mb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::MiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::MB).to_string(),
|
||||||
)),
|
)),
|
||||||
"gb" => Ok(UntaggedValue::string(
|
"mib" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::GB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::MiB).to_string(),
|
||||||
)),
|
)),
|
||||||
"gib" => Ok(UntaggedValue::string(
|
"gb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::GiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::GB).to_string(),
|
||||||
)),
|
)),
|
||||||
"tb" => Ok(UntaggedValue::string(
|
"gib" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::TB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::GiB).to_string(),
|
||||||
)),
|
)),
|
||||||
"tib" => Ok(UntaggedValue::string(
|
"tb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::TiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::TB).to_string(),
|
||||||
)),
|
)),
|
||||||
"pb" => Ok(UntaggedValue::string(
|
"tib" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::PB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::TiB).to_string(),
|
||||||
)),
|
)),
|
||||||
"pib" => Ok(UntaggedValue::string(
|
"pb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::PiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::PB).to_string(),
|
||||||
)),
|
)),
|
||||||
"eb" => Ok(UntaggedValue::string(
|
"pib" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::EB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::PiB).to_string(),
|
||||||
)),
|
)),
|
||||||
"eib" => Ok(UntaggedValue::string(
|
"eb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::EiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::EB).to_string(),
|
||||||
)),
|
)),
|
||||||
"zb" => Ok(UntaggedValue::string(
|
"eib" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::ZB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::EiB).to_string(),
|
||||||
)),
|
)),
|
||||||
"zib" => Ok(UntaggedValue::string(
|
"zb" => Ok(UntaggedValue::string(
|
||||||
byte.get_adjusted_unit(byte_unit::ByteUnit::ZiB).to_string(),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::ZB).to_string(),
|
||||||
)),
|
)),
|
||||||
_ => Err(ShellError::labeled_error(
|
"zib" => Ok(UntaggedValue::string(
|
||||||
format!("Invalid format code: {:}", format.item()),
|
byte.get_adjusted_unit(byte_unit::ByteUnit::ZiB).to_string(),
|
||||||
"invalid format",
|
)),
|
||||||
format.tag(),
|
_ => Err(ShellError::labeled_error(
|
||||||
)),
|
format!("Invalid format code: {:}", format.item()),
|
||||||
};
|
"invalid format",
|
||||||
match value {
|
format.tag(),
|
||||||
Ok(b) => Ok(Value { value: b, ..bytes }),
|
)),
|
||||||
Err(e) => Err(e),
|
};
|
||||||
|
match value {
|
||||||
|
Ok(b) => Ok(Value { value: b, ..bytes }),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(ShellError::labeled_error(
|
||||||
|
"Value too large to fit in 128 bits",
|
||||||
|
"value too large to fit in format",
|
||||||
|
format.span(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::labeled_error(
|
_ => Err(ShellError::labeled_error(
|
||||||
|
|
|
@ -59,12 +59,9 @@ impl WholeStreamCommand for SubCommand {
|
||||||
|
|
||||||
fn to_byte(value: &Value) -> Option<Value> {
|
fn to_byte(value: &Value) -> Option<Value> {
|
||||||
match &value.value {
|
match &value.value {
|
||||||
UntaggedValue::Primitive(Primitive::Int(num)) => Some(
|
UntaggedValue::Primitive(Primitive::Int(num)) => {
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(convert_number_to_u64(&Number::Int(
|
Some(UntaggedValue::Primitive(Primitive::Filesize(num.clone())).into_untagged_value())
|
||||||
num.clone(),
|
}
|
||||||
))))
|
|
||||||
.into_untagged_value(),
|
|
||||||
),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +92,7 @@ pub fn average(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
||||||
..
|
..
|
||||||
} => UntaggedValue::int(*num as usize).into_untagged_value(),
|
} => UntaggedValue::int(num.clone()).into_untagged_value(),
|
||||||
other => other.clone(),
|
other => other.clone(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
@ -116,7 +113,7 @@ pub fn average(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let left = UntaggedValue::from(Primitive::Int(num.into()));
|
let left = UntaggedValue::from(Primitive::Int(num));
|
||||||
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -137,7 +137,7 @@ fn compute_average(values: &[Value], name: impl Into<Tag>) -> Result<Value, Shel
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let left = UntaggedValue::from(Primitive::Int(num.into()));
|
let left = UntaggedValue::from(Primitive::Int(num));
|
||||||
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -3,10 +3,7 @@ use crate::commands::math::utils::run_with_function;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{Primitive, Signature, UntaggedValue, Value};
|
||||||
hir::{convert_number_to_u64, Number},
|
|
||||||
Primitive, Signature, UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
|
||||||
|
@ -51,12 +48,9 @@ impl WholeStreamCommand for SubCommand {
|
||||||
|
|
||||||
fn to_byte(value: &Value) -> Option<Value> {
|
fn to_byte(value: &Value) -> Option<Value> {
|
||||||
match &value.value {
|
match &value.value {
|
||||||
UntaggedValue::Primitive(Primitive::Int(num)) => Some(
|
UntaggedValue::Primitive(Primitive::Int(num)) => {
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(convert_number_to_u64(&Number::Int(
|
Some(UntaggedValue::Primitive(Primitive::Filesize(num.clone())).into_untagged_value())
|
||||||
num.clone(),
|
}
|
||||||
))))
|
|
||||||
.into_untagged_value(),
|
|
||||||
),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +72,7 @@ pub fn product(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
||||||
..
|
..
|
||||||
} => UntaggedValue::int(*num as usize).into_untagged_value(),
|
} => UntaggedValue::int(num.clone()).into_untagged_value(),
|
||||||
other => other.clone(),
|
other => other.clone(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
|
|
@ -4,10 +4,7 @@ use crate::prelude::*;
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
|
|
||||||
use nu_protocol::{
|
use nu_protocol::{Primitive, Signature, UntaggedValue, Value};
|
||||||
hir::{convert_number_to_u64, Number},
|
|
||||||
Primitive, Signature, UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
|
||||||
|
@ -59,12 +56,9 @@ impl WholeStreamCommand for SubCommand {
|
||||||
|
|
||||||
fn to_byte(value: &Value) -> Option<Value> {
|
fn to_byte(value: &Value) -> Option<Value> {
|
||||||
match &value.value {
|
match &value.value {
|
||||||
UntaggedValue::Primitive(Primitive::Int(num)) => Some(
|
UntaggedValue::Primitive(Primitive::Int(num)) => {
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(convert_number_to_u64(&Number::Int(
|
Some(UntaggedValue::Primitive(Primitive::Filesize(num.clone())).into_untagged_value())
|
||||||
num.clone(),
|
}
|
||||||
))))
|
|
||||||
.into_untagged_value(),
|
|
||||||
),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +84,7 @@ pub fn summation(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
||||||
..
|
..
|
||||||
} => UntaggedValue::int(*num as usize).into_untagged_value(),
|
} => UntaggedValue::int(num.clone()).into_untagged_value(),
|
||||||
other => other.clone(),
|
other => other.clone(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
|
|
@ -130,7 +130,7 @@ fn sum_of_squares(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(num)),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
UntaggedValue::from(Primitive::Int(num.clone().into()))
|
UntaggedValue::from(Primitive::Int(num.clone()))
|
||||||
},
|
},
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(num),
|
value: UntaggedValue::Primitive(num),
|
||||||
|
|
|
@ -116,7 +116,7 @@ pub fn clone_tagged_value(v: &Value) -> Value {
|
||||||
UntaggedValue::Primitive(Primitive::FilePath(x.clone()))
|
UntaggedValue::Primitive(Primitive::FilePath(x.clone()))
|
||||||
}
|
}
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(b)) => {
|
UntaggedValue::Primitive(Primitive::Filesize(b)) => {
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(*b))
|
UntaggedValue::Primitive(Primitive::Filesize(b.clone()))
|
||||||
}
|
}
|
||||||
UntaggedValue::Primitive(Primitive::Date(d)) => {
|
UntaggedValue::Primitive(Primitive::Date(d)) => {
|
||||||
UntaggedValue::Primitive(Primitive::Date(*d))
|
UntaggedValue::Primitive(Primitive::Date(*d))
|
||||||
|
|
|
@ -40,7 +40,17 @@ impl WholeStreamCommand for ToTOML {
|
||||||
fn helper(v: &Value) -> Result<toml::Value, ShellError> {
|
fn helper(v: &Value) -> Result<toml::Value, ShellError> {
|
||||||
Ok(match &v.value {
|
Ok(match &v.value {
|
||||||
UntaggedValue::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
UntaggedValue::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(b)) => toml::Value::Integer(*b as i64),
|
UntaggedValue::Primitive(Primitive::Filesize(b)) => {
|
||||||
|
if let Some(value) = b.to_i64() {
|
||||||
|
toml::Value::Integer(value)
|
||||||
|
} else {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"Value too large to write to toml",
|
||||||
|
"value too large for toml",
|
||||||
|
v.tag.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
UntaggedValue::Primitive(Primitive::Duration(i)) => toml::Value::String(i.to_string()),
|
UntaggedValue::Primitive(Primitive::Duration(i)) => toml::Value::String(i.to_string()),
|
||||||
UntaggedValue::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
UntaggedValue::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
||||||
UntaggedValue::Primitive(Primitive::EndOfStream) => {
|
UntaggedValue::Primitive(Primitive::EndOfStream) => {
|
||||||
|
|
|
@ -129,20 +129,18 @@ pub fn coerce_compare_primitive(
|
||||||
(Int(left), Decimal(right)) => {
|
(Int(left), Decimal(right)) => {
|
||||||
CompareValues::Decimals(BigDecimal::zero() + left, right.clone())
|
CompareValues::Decimals(BigDecimal::zero() + left, right.clone())
|
||||||
}
|
}
|
||||||
(Int(left), Filesize(right)) => CompareValues::Ints(left.clone(), BigInt::from(*right)),
|
(Int(left), Filesize(right)) => CompareValues::Ints(left.clone(), right.clone()),
|
||||||
(Decimal(left), Decimal(right)) => CompareValues::Decimals(left.clone(), right.clone()),
|
(Decimal(left), Decimal(right)) => CompareValues::Decimals(left.clone(), right.clone()),
|
||||||
(Decimal(left), Int(right)) => {
|
(Decimal(left), Int(right)) => {
|
||||||
CompareValues::Decimals(left.clone(), BigDecimal::zero() + right)
|
CompareValues::Decimals(left.clone(), BigDecimal::zero() + right)
|
||||||
}
|
}
|
||||||
(Decimal(left), Filesize(right)) => {
|
(Decimal(left), Filesize(right)) => {
|
||||||
CompareValues::Decimals(left.clone(), BigDecimal::from(*right))
|
CompareValues::Decimals(left.clone(), BigDecimal::from(right.clone()))
|
||||||
}
|
}
|
||||||
(Filesize(left), Filesize(right)) => {
|
(Filesize(left), Filesize(right)) => CompareValues::Ints(left.clone(), right.clone()),
|
||||||
CompareValues::Ints(BigInt::from(*left), BigInt::from(*right))
|
(Filesize(left), Int(right)) => CompareValues::Ints(left.clone(), right.clone()),
|
||||||
}
|
|
||||||
(Filesize(left), Int(right)) => CompareValues::Ints(BigInt::from(*left), right.clone()),
|
|
||||||
(Filesize(left), Decimal(right)) => {
|
(Filesize(left), Decimal(right)) => {
|
||||||
CompareValues::Decimals(BigDecimal::from(*left), right.clone())
|
CompareValues::Decimals(BigDecimal::from(left.clone()), right.clone())
|
||||||
}
|
}
|
||||||
(Nothing, Nothing) => CompareValues::Booleans(true, true),
|
(Nothing, Nothing) => CompareValues::Booleans(true, true),
|
||||||
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
|
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub enum InlineShape {
|
||||||
Int(BigInt),
|
Int(BigInt),
|
||||||
Decimal(BigDecimal),
|
Decimal(BigDecimal),
|
||||||
Range(Box<InlineRange>),
|
Range(Box<InlineRange>),
|
||||||
Bytesize(u64),
|
Bytesize(BigInt),
|
||||||
String(String),
|
String(String),
|
||||||
Line(String),
|
Line(String),
|
||||||
ColumnPath(ColumnPath),
|
ColumnPath(ColumnPath),
|
||||||
|
@ -68,7 +68,7 @@ impl InlineShape {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Primitive::Decimal(decimal) => InlineShape::Decimal(decimal.clone()),
|
Primitive::Decimal(decimal) => InlineShape::Decimal(decimal.clone()),
|
||||||
Primitive::Filesize(bytesize) => InlineShape::Bytesize(*bytesize),
|
Primitive::Filesize(bytesize) => InlineShape::Bytesize(bytesize.clone()),
|
||||||
Primitive::String(string) => InlineShape::String(string.clone()),
|
Primitive::String(string) => InlineShape::String(string.clone()),
|
||||||
Primitive::ColumnPath(path) => InlineShape::ColumnPath(path.clone()),
|
Primitive::ColumnPath(path) => InlineShape::ColumnPath(path.clone()),
|
||||||
Primitive::GlobPattern(pattern) => InlineShape::GlobPattern(pattern.clone()),
|
Primitive::GlobPattern(pattern) => InlineShape::GlobPattern(pattern.clone()),
|
||||||
|
@ -128,7 +128,9 @@ impl InlineShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_bytes(bytesize: &u64) -> (DbgDocBldr, String) {
|
pub fn format_bytes(bytesize: &BigInt) -> (DbgDocBldr, String) {
|
||||||
|
use bigdecimal::ToPrimitive;
|
||||||
|
|
||||||
// get the config value, if it doesn't exist make it 'auto' so it works how it originally did
|
// get the config value, if it doesn't exist make it 'auto' so it works how it originally did
|
||||||
let filesize_format_var = crate::config::config(Tag::unknown())
|
let filesize_format_var = crate::config::config(Tag::unknown())
|
||||||
.expect("unable to get the config.toml file")
|
.expect("unable to get the config.toml file")
|
||||||
|
@ -155,32 +157,41 @@ impl InlineShape {
|
||||||
_ => (byte_unit::ByteUnit::B, "auto"),
|
_ => (byte_unit::ByteUnit::B, "auto"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let byte = byte_unit::Byte::from_bytes(*bytesize as u128);
|
if let Some(value) = bytesize.to_u128() {
|
||||||
let byte = if filesize_format.0 == byte_unit::ByteUnit::B && filesize_format.1 == "auto" {
|
let byte = byte_unit::Byte::from_bytes(value);
|
||||||
byte.get_appropriate_unit(false)
|
let byte = if filesize_format.0 == byte_unit::ByteUnit::B && filesize_format.1 == "auto"
|
||||||
} else {
|
{
|
||||||
byte.get_adjusted_unit(filesize_format.0)
|
byte.get_appropriate_unit(false)
|
||||||
};
|
} else {
|
||||||
|
byte.get_adjusted_unit(filesize_format.0)
|
||||||
|
};
|
||||||
|
|
||||||
match byte.get_unit() {
|
match byte.get_unit() {
|
||||||
byte_unit::ByteUnit::B => {
|
byte_unit::ByteUnit::B => {
|
||||||
let locale_byte = byte.get_value() as u64;
|
let locale_byte = byte.get_value() as u64;
|
||||||
let locale_byte_string = locale_byte.to_formatted_string(&Locale::en);
|
let locale_byte_string = locale_byte.to_formatted_string(&Locale::en);
|
||||||
if filesize_format.1 == "auto" {
|
if filesize_format.1 == "auto" {
|
||||||
let doc = (DbgDocBldr::primitive(locale_byte_string)
|
let doc = (DbgDocBldr::primitive(locale_byte_string)
|
||||||
+ DbgDocBldr::space()
|
+ DbgDocBldr::space()
|
||||||
+ DbgDocBldr::kind("B"))
|
+ DbgDocBldr::kind("B"))
|
||||||
.group();
|
.group();
|
||||||
(doc.clone(), InlineShape::render_doc(&doc))
|
(doc.clone(), InlineShape::render_doc(&doc))
|
||||||
} else {
|
} else {
|
||||||
let doc = (DbgDocBldr::primitive(locale_byte_string)).group();
|
let doc = (DbgDocBldr::primitive(locale_byte_string)).group();
|
||||||
|
(doc.clone(), InlineShape::render_doc(&doc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let doc = DbgDocBldr::primitive(byte.format(1));
|
||||||
(doc.clone(), InlineShape::render_doc(&doc))
|
(doc.clone(), InlineShape::render_doc(&doc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
} else {
|
||||||
let doc = DbgDocBldr::primitive(byte.format(1));
|
let doc = (DbgDocBldr::primitive(format!("{}", bytesize))
|
||||||
(doc.clone(), InlineShape::render_doc(&doc))
|
+ DbgDocBldr::space()
|
||||||
}
|
+ DbgDocBldr::kind("B"))
|
||||||
|
.group();
|
||||||
|
(doc.clone(), InlineShape::render_doc(&doc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,21 @@ fn collect_values(input: &[Value]) -> Result<Vec<toml::Value>, ShellError> {
|
||||||
// Helper method to recursively convert nu_protocol::Value -> toml::Value
|
// Helper method to recursively convert nu_protocol::Value -> toml::Value
|
||||||
// This shouldn't be called at the top-level
|
// This shouldn't be called at the top-level
|
||||||
fn helper(v: &Value) -> Result<toml::Value, ShellError> {
|
fn helper(v: &Value) -> Result<toml::Value, ShellError> {
|
||||||
|
use bigdecimal::ToPrimitive;
|
||||||
|
|
||||||
Ok(match &v.value {
|
Ok(match &v.value {
|
||||||
UntaggedValue::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
UntaggedValue::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(b)) => toml::Value::Integer(*b as i64),
|
UntaggedValue::Primitive(Primitive::Filesize(b)) => {
|
||||||
|
if let Some(value) = b.to_i64() {
|
||||||
|
toml::Value::Integer(value)
|
||||||
|
} else {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"Value too large to convert to toml value",
|
||||||
|
"value too large",
|
||||||
|
v.tag.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
UntaggedValue::Primitive(Primitive::Duration(i)) => toml::Value::String(i.to_string()),
|
UntaggedValue::Primitive(Primitive::Duration(i)) => toml::Value::String(i.to_string()),
|
||||||
UntaggedValue::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
UntaggedValue::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
||||||
UntaggedValue::Primitive(Primitive::EndOfStream) => {
|
UntaggedValue::Primitive(Primitive::EndOfStream) => {
|
||||||
|
|
|
@ -81,21 +81,12 @@ pub fn unsafe_compute_values(
|
||||||
match (left, right) {
|
match (left, right) {
|
||||||
(UntaggedValue::Primitive(lhs), UntaggedValue::Primitive(rhs)) => match (lhs, rhs) {
|
(UntaggedValue::Primitive(lhs), UntaggedValue::Primitive(rhs)) => match (lhs, rhs) {
|
||||||
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
|
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
|
||||||
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(x + y))),
|
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
|
||||||
Operator::Minus => Ok(UntaggedValue::Primitive(Primitive::Int(x - y))),
|
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Filesize(x / y))),
|
||||||
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Int(x * y))),
|
|
||||||
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Decimal(
|
|
||||||
bigdecimal::BigDecimal::from(*x) / bigdecimal::BigDecimal::from(y.clone()),
|
|
||||||
))),
|
|
||||||
_ => Err((left.type_name(), right.type_name())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
},
|
},
|
||||||
(Primitive::Int(x), Primitive::Filesize(y)) => match operator {
|
(Primitive::Int(x), Primitive::Filesize(y)) => match operator {
|
||||||
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(x + y))),
|
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
|
||||||
Operator::Minus => Ok(UntaggedValue::Primitive(Primitive::Int(x - y))),
|
|
||||||
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Int(x * y))),
|
|
||||||
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Decimal(
|
|
||||||
bigdecimal::BigDecimal::from(x.clone()) / bigdecimal::BigDecimal::from(*y),
|
|
||||||
))),
|
|
||||||
_ => Err((left.type_name(), right.type_name())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
},
|
},
|
||||||
_ => Err((left.type_name(), right.type_name())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
|
@ -120,8 +111,12 @@ pub fn compute_values(
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Filesize(result)))
|
Ok(UntaggedValue::Primitive(Primitive::Filesize(result)))
|
||||||
}
|
}
|
||||||
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
|
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
|
||||||
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Int(x * y))),
|
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
|
||||||
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Int(x / y))),
|
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Filesize(x / y))),
|
||||||
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
|
},
|
||||||
|
(Primitive::Int(x), Primitive::Filesize(y)) => match operator {
|
||||||
|
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
|
||||||
_ => Err((left.type_name(), right.type_name())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
},
|
},
|
||||||
(Primitive::Int(x), Primitive::Int(y)) => match operator {
|
(Primitive::Int(x), Primitive::Int(y)) => match operator {
|
||||||
|
|
|
@ -631,8 +631,8 @@ impl Unit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filesize(size_in_bytes: u64) -> UntaggedValue {
|
pub fn filesize(size_in_bytes: impl Into<BigInt>) -> UntaggedValue {
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(size_in_bytes))
|
UntaggedValue::Primitive(Primitive::Filesize(size_in_bytes.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn duration(nanos: BigInt) -> UntaggedValue {
|
pub fn duration(nanos: BigInt) -> UntaggedValue {
|
||||||
|
|
|
@ -186,7 +186,7 @@ impl UntaggedValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for creating filesize values
|
/// Helper for creating filesize values
|
||||||
pub fn filesize(s: impl Into<u64>) -> UntaggedValue {
|
pub fn filesize(s: impl Into<BigInt>) -> UntaggedValue {
|
||||||
UntaggedValue::Primitive(Primitive::Filesize(s.into()))
|
UntaggedValue::Primitive(Primitive::Filesize(s.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +713,7 @@ impl U64Ext for u64 {
|
||||||
|
|
||||||
fn to_filesize_value(&self, the_tag: Tag) -> Value {
|
fn to_filesize_value(&self, the_tag: Tag) -> Value {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Primitive(Primitive::Filesize(*self)),
|
value: UntaggedValue::Primitive(Primitive::Filesize(BigInt::from(*self))),
|
||||||
tag: the_tag,
|
tag: the_tag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub enum Primitive {
|
||||||
#[serde(with = "serde_bigdecimal")]
|
#[serde(with = "serde_bigdecimal")]
|
||||||
Decimal(BigDecimal),
|
Decimal(BigDecimal),
|
||||||
/// A count in the number of bytes, used as a filesize
|
/// A count in the number of bytes, used as a filesize
|
||||||
Filesize(u64),
|
Filesize(BigInt),
|
||||||
/// A string value
|
/// A string value
|
||||||
String(String),
|
String(String),
|
||||||
/// A path to travel to reach a value in a table
|
/// A path to travel to reach a value in a table
|
||||||
|
@ -254,17 +254,21 @@ pub fn format_primitive(primitive: &Primitive, field_name: Option<&String>) -> S
|
||||||
Primitive::EndOfStream => String::new(),
|
Primitive::EndOfStream => String::new(),
|
||||||
Primitive::FilePath(p) => format!("{}", p.display()),
|
Primitive::FilePath(p) => format!("{}", p.display()),
|
||||||
Primitive::Filesize(num_bytes) => {
|
Primitive::Filesize(num_bytes) => {
|
||||||
let byte = byte_unit::Byte::from_bytes(*num_bytes as u128);
|
if let Some(value) = num_bytes.to_u128() {
|
||||||
|
let byte = byte_unit::Byte::from_bytes(value);
|
||||||
|
|
||||||
if byte.get_bytes() == 0u128 {
|
if byte.get_bytes() == 0u128 {
|
||||||
return "—".to_string();
|
return "—".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
let byte = byte.get_appropriate_unit(false);
|
let byte = byte.get_appropriate_unit(false);
|
||||||
|
|
||||||
match byte.get_unit() {
|
match byte.get_unit() {
|
||||||
byte_unit::ByteUnit::B => format!("{} B ", byte.get_value()),
|
byte_unit::ByteUnit::B => format!("{} B ", byte.get_value()),
|
||||||
_ => byte.format(1),
|
_ => byte.format(1),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
format!("{} B", num_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Primitive::Duration(duration) => format_duration(duration),
|
Primitive::Duration(duration) => format_duration(duration),
|
||||||
|
|
|
@ -750,6 +750,53 @@ fn range_with_mixed_types() {
|
||||||
assert_eq!(actual.out, "55");
|
assert_eq!(actual.out, "55");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn filesize_math() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".",
|
||||||
|
r#"
|
||||||
|
= 100 * 10kb
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "1.0 MB");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn filesize_math2() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".",
|
||||||
|
r#"
|
||||||
|
= 100 / 10kb
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(actual.err.contains("Coercion"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn filesize_math3() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".",
|
||||||
|
r#"
|
||||||
|
= 100kb / 10
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "10.2 KB");
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn filesize_math4() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".",
|
||||||
|
r#"
|
||||||
|
= 100kb * 5
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "512.0 KB");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exclusive_range_with_mixed_types() {
|
fn exclusive_range_with_mixed_types() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
|
|
Loading…
Reference in a new issue