Move filesize to use bigint (#2984)

* Move filesize to be bigint-sized

* Add tests and fix filesize display

* clippy
This commit is contained in:
Jonathan Turner
2021-01-30 11:35:18 +13:00
committed by GitHub
parent 7b4cbd7ce9
commit 44e088c6fe
17 changed files with 227 additions and 148 deletions

View File

@ -129,20 +129,18 @@ pub fn coerce_compare_primitive(
(Int(left), Decimal(right)) => {
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), Int(right)) => {
CompareValues::Decimals(left.clone(), BigDecimal::zero() + right)
}
(Decimal(left), Filesize(right)) => {
CompareValues::Decimals(left.clone(), BigDecimal::from(*right))
CompareValues::Decimals(left.clone(), BigDecimal::from(right.clone()))
}
(Filesize(left), Filesize(right)) => {
CompareValues::Ints(BigInt::from(*left), BigInt::from(*right))
}
(Filesize(left), Int(right)) => CompareValues::Ints(BigInt::from(*left), right.clone()),
(Filesize(left), Filesize(right)) => CompareValues::Ints(left.clone(), right.clone()),
(Filesize(left), Int(right)) => CompareValues::Ints(left.clone(), right.clone()),
(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),
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),

View File

@ -24,7 +24,7 @@ pub enum InlineShape {
Int(BigInt),
Decimal(BigDecimal),
Range(Box<InlineRange>),
Bytesize(u64),
Bytesize(BigInt),
String(String),
Line(String),
ColumnPath(ColumnPath),
@ -68,7 +68,7 @@ impl InlineShape {
}))
}
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::ColumnPath(path) => InlineShape::ColumnPath(path.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
let filesize_format_var = crate::config::config(Tag::unknown())
.expect("unable to get the config.toml file")
@ -155,32 +157,41 @@ impl InlineShape {
_ => (byte_unit::ByteUnit::B, "auto"),
};
let byte = byte_unit::Byte::from_bytes(*bytesize as u128);
let byte = if filesize_format.0 == byte_unit::ByteUnit::B && filesize_format.1 == "auto" {
byte.get_appropriate_unit(false)
} else {
byte.get_adjusted_unit(filesize_format.0)
};
if let Some(value) = bytesize.to_u128() {
let byte = byte_unit::Byte::from_bytes(value);
let byte = if filesize_format.0 == byte_unit::ByteUnit::B && filesize_format.1 == "auto"
{
byte.get_appropriate_unit(false)
} else {
byte.get_adjusted_unit(filesize_format.0)
};
match byte.get_unit() {
byte_unit::ByteUnit::B => {
let locale_byte = byte.get_value() as u64;
let locale_byte_string = locale_byte.to_formatted_string(&Locale::en);
if filesize_format.1 == "auto" {
let doc = (DbgDocBldr::primitive(locale_byte_string)
+ DbgDocBldr::space()
+ DbgDocBldr::kind("B"))
.group();
(doc.clone(), InlineShape::render_doc(&doc))
} else {
let doc = (DbgDocBldr::primitive(locale_byte_string)).group();
match byte.get_unit() {
byte_unit::ByteUnit::B => {
let locale_byte = byte.get_value() as u64;
let locale_byte_string = locale_byte.to_formatted_string(&Locale::en);
if filesize_format.1 == "auto" {
let doc = (DbgDocBldr::primitive(locale_byte_string)
+ DbgDocBldr::space()
+ DbgDocBldr::kind("B"))
.group();
(doc.clone(), InlineShape::render_doc(&doc))
} else {
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))
}
}
_ => {
let doc = DbgDocBldr::primitive(byte.format(1));
(doc.clone(), InlineShape::render_doc(&doc))
}
} else {
let doc = (DbgDocBldr::primitive(format!("{}", bytesize))
+ DbgDocBldr::space()
+ DbgDocBldr::kind("B"))
.group();
(doc.clone(), InlineShape::render_doc(&doc))
}
}

View File

@ -61,9 +61,21 @@ fn collect_values(input: &[Value]) -> Result<Vec<toml::Value>, ShellError> {
// Helper method to recursively convert nu_protocol::Value -> toml::Value
// This shouldn't be called at the top-level
fn helper(v: &Value) -> Result<toml::Value, ShellError> {
use bigdecimal::ToPrimitive;
Ok(match &v.value {
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::Date(d)) => toml::Value::String(d.to_string()),
UntaggedValue::Primitive(Primitive::EndOfStream) => {

View File

@ -81,21 +81,12 @@ pub fn unsafe_compute_values(
match (left, right) {
(UntaggedValue::Primitive(lhs), UntaggedValue::Primitive(rhs)) => match (lhs, rhs) {
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(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) / bigdecimal::BigDecimal::from(y.clone()),
))),
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(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::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(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),
))),
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
_ => 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)))
}
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Int(x * y))),
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Int(x / y))),
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(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())),
},
(Primitive::Int(x), Primitive::Int(y)) => match operator {