Make the default int an i64 (#3428)

* Make the default int an i64

* fmt

* Fix random integer

* Treat pids as i64 for now
This commit is contained in:
JT
2021-05-14 20:35:09 +12:00
committed by GitHub
parent 440a589f9e
commit d79a3130b8
59 changed files with 693 additions and 284 deletions

View File

@ -10,7 +10,6 @@ use nu_protocol::{
use nu_source::{Span, Tag};
use nu_value_ext::ValueExt;
use num_bigint::BigInt;
use num_traits::Zero;
use serde::{Deserialize, Serialize};
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, new, Serialize)]
@ -72,7 +71,9 @@ pub fn reject_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>) -> Val
}
pub enum CompareValues {
Ints(BigInt, BigInt),
Ints(i64, i64),
Filesizes(u64, u64),
BigInts(BigInt, BigInt),
Decimals(BigDecimal, BigDecimal),
String(String, String),
Date(DateTime<FixedOffset>, DateTime<FixedOffset>),
@ -83,7 +84,9 @@ pub enum CompareValues {
impl CompareValues {
pub fn compare(&self) -> std::cmp::Ordering {
match self {
CompareValues::BigInts(left, right) => left.cmp(right),
CompareValues::Ints(left, right) => left.cmp(right),
CompareValues::Filesizes(left, right) => left.cmp(right),
CompareValues::Decimals(left, right) => left.cmp(right),
CompareValues::String(left, right) => left.cmp(right),
CompareValues::Date(left, right) => left.cmp(right),
@ -125,22 +128,34 @@ pub fn coerce_compare_primitive(
use Primitive::*;
Ok(match (left, right) {
(Int(left), Int(right)) => CompareValues::Ints(left.clone(), right.clone()),
(Int(left), Decimal(right)) => {
CompareValues::Decimals(BigDecimal::zero() + left, right.clone())
(Int(left), Int(right)) => CompareValues::Ints(*left, *right),
(Int(left), BigInt(right)) => {
CompareValues::BigInts(num_bigint::BigInt::from(*left), right.clone())
}
(BigInt(left), Int(right)) => {
CompareValues::BigInts(left.clone(), num_bigint::BigInt::from(*right))
}
(BigInt(left), BigInt(right)) => CompareValues::BigInts(left.clone(), right.clone()),
(Int(left), Decimal(right)) => {
CompareValues::Decimals(BigDecimal::from(*left), right.clone())
}
(BigInt(left), Decimal(right)) => {
CompareValues::Decimals(BigDecimal::from(left.clone()), right.clone())
}
(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)
CompareValues::Decimals(left.clone(), BigDecimal::from(*right))
}
(Decimal(left), Filesize(right)) => {
(Decimal(left), BigInt(right)) => {
CompareValues::Decimals(left.clone(), BigDecimal::from(right.clone()))
}
(Filesize(left), Filesize(right)) => CompareValues::Ints(left.clone(), right.clone()),
(Filesize(left), Int(right)) => CompareValues::Ints(left.clone(), right.clone()),
(Decimal(left), Filesize(right)) => {
CompareValues::Decimals(left.clone(), BigDecimal::from(*right))
}
(Filesize(left), Filesize(right)) => CompareValues::Filesizes(*left, *right),
(Filesize(left), Decimal(right)) => {
CompareValues::Decimals(BigDecimal::from(left.clone()), right.clone())
CompareValues::Decimals(BigDecimal::from(*left), right.clone())
}
(Nothing, Nothing) => CompareValues::Booleans(true, true),
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),

View File

@ -21,10 +21,11 @@ pub struct InlineRange {
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
pub enum InlineShape {
Nothing,
Int(BigInt),
Int(i64),
BigInt(BigInt),
Decimal(BigDecimal),
Range(Box<InlineRange>),
Bytesize(BigInt),
Bytesize(u64),
String(String),
Line(String),
ColumnPath(ColumnPath),
@ -74,7 +75,8 @@ impl InlineShape {
pub fn from_primitive(primitive: &Primitive) -> InlineShape {
match primitive {
Primitive::Nothing => InlineShape::Nothing,
Primitive::Int(int) => InlineShape::Int(int.clone()),
Primitive::Int(int) => InlineShape::Int(*int),
Primitive::BigInt(int) => InlineShape::BigInt(int.clone()),
Primitive::Range(range) => {
let (left, left_inclusion) = &range.from;
let (right, right_inclusion) = &range.to;
@ -85,7 +87,7 @@ impl InlineShape {
}))
}
Primitive::Decimal(decimal) => InlineShape::Decimal(decimal.clone()),
Primitive::Filesize(bytesize) => InlineShape::Bytesize(bytesize.clone()),
Primitive::Filesize(bytesize) => InlineShape::Bytesize(*bytesize),
Primitive::String(string) => InlineShape::String(string.clone()),
Primitive::ColumnPath(path) => InlineShape::ColumnPath(path.clone()),
Primitive::GlobPattern(pattern) => InlineShape::GlobPattern(pattern.clone()),
@ -147,7 +149,7 @@ impl InlineShape {
}
}
pub fn format_bytes(bytesize: &BigInt, forced_format: Option<&str>) -> (DbgDocBldr, String) {
pub fn format_bytes(bytesize: u64, forced_format: Option<&str>) -> (DbgDocBldr, String) {
use bigdecimal::ToPrimitive;
// get the config value, if it doesn't exist make it 'auto' so it works how it originally did
@ -236,6 +238,7 @@ impl PrettyDebug for FormatInlineShape {
match &self.shape {
InlineShape::Nothing => DbgDocBldr::blank(),
InlineShape::Int(int) => DbgDocBldr::primitive(format!("{}", int)),
InlineShape::BigInt(int) => DbgDocBldr::primitive(format!("{}", int)),
InlineShape::Decimal(decimal) => DbgDocBldr::description(format_primitive(
&Primitive::Decimal(decimal.clone()),
None,
@ -258,7 +261,7 @@ impl PrettyDebug for FormatInlineShape {
+ right.clone().format().pretty()
}
InlineShape::Bytesize(bytesize) => {
let bytes = InlineShape::format_bytes(bytesize, None);
let bytes = InlineShape::format_bytes(*bytesize, None);
bytes.0
}
InlineShape::String(string) => DbgDocBldr::primitive(string),

View File

@ -93,7 +93,8 @@ fn helper(v: &Value) -> Result<toml::Value, ShellError> {
UntaggedValue::Primitive(Primitive::Decimal(f)) => {
toml::Value::Float(f.tagged(&v.tag).coerce_into("converting to TOML float")?)
}
UntaggedValue::Primitive(Primitive::Int(i)) => {
UntaggedValue::Primitive(Primitive::Int(i)) => toml::Value::Integer(*i),
UntaggedValue::Primitive(Primitive::BigInt(i)) => {
toml::Value::Integer(i.tagged(&v.tag).coerce_into("converting to TOML integer")?)
}
UntaggedValue::Primitive(Primitive::Nothing) => {
@ -108,10 +109,7 @@ fn helper(v: &Value) -> Result<toml::Value, ShellError> {
path.iter()
.map(|x| match &x.unspanned {
UnspannedPathMember::String(string) => Ok(toml::Value::String(string.clone())),
UnspannedPathMember::Int(int) => Ok(toml::Value::Integer(
int.tagged(&v.tag)
.coerce_into("converting to TOML integer")?,
)),
UnspannedPathMember::Int(int) => Ok(toml::Value::Integer(*int)),
})
.collect::<Result<Vec<toml::Value>, ShellError>>()?,
),

View File

@ -8,6 +8,7 @@ pub fn number(number: impl Into<Number>) -> Primitive {
let number = number.into();
match number {
Number::BigInt(int) => Primitive::BigInt(int),
Number::Int(int) => Primitive::Int(int),
Number::Decimal(decimal) => Primitive::Decimal(decimal),
}

View File

@ -52,6 +52,10 @@ impl ExtractType for i64 {
&Value {
value: UntaggedValue::Primitive(Primitive::Int(int)),
..
} => Ok(*int),
&Value {
value: UntaggedValue::Primitive(Primitive::BigInt(int)),
..
} => Ok(int.tagged(&value.tag).coerce_into("converting to i64")?),
other => Err(ShellError::type_error("Integer", other.spanned_type_name())),
}
@ -64,10 +68,13 @@ impl ExtractType for u64 {
match &value {
&Value {
value: UntaggedValue::Primitive(Primitive::Int(int)),
value: UntaggedValue::Primitive(Primitive::BigInt(int)),
..
} => Ok(int.tagged(&value.tag).coerce_into("converting to u64")?),
other => Err(ShellError::type_error("Integer", other.spanned_type_name())),
other => Err(ShellError::type_error(
"Big Integer",
other.spanned_type_name(),
)),
}
}
}

View File

@ -28,7 +28,7 @@ impl Labels {
}
pub fn grouping_total(&self) -> Value {
UntaggedValue::int(self.x.len()).into_untagged_value()
UntaggedValue::int(self.x.len() as i64).into_untagged_value()
}
pub fn splits(&self) -> impl Iterator<Item = &String> {
@ -36,7 +36,7 @@ impl Labels {
}
pub fn splits_total(&self) -> Value {
UntaggedValue::int(self.y.len()).into_untagged_value()
UntaggedValue::big_int(self.y.len()).into_untagged_value()
}
}

View File

@ -8,6 +8,7 @@ use nu_protocol::ShellTypeName;
use nu_protocol::{Primitive, Type, UntaggedValue};
use nu_source::{DebugDocBuilder, PrettyDebug, Span, Tagged};
use nu_table::TextStyle;
use num_bigint::BigInt;
use num_traits::{ToPrimitive, Zero};
use std::collections::HashMap;
@ -81,12 +82,18 @@ 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::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Filesize(x / y))),
Operator::Multiply => {
Ok(UntaggedValue::Primitive(Primitive::Filesize(x * *y as u64)))
}
Operator::Divide => {
Ok(UntaggedValue::Primitive(Primitive::Filesize(x / *y as u64)))
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::Int(x), Primitive::Filesize(y)) => match operator {
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
Operator::Multiply => {
Ok(UntaggedValue::Primitive(Primitive::Filesize(*x as u64 * y)))
}
_ => Err((left.type_name(), right.type_name())),
},
_ => Err((left.type_name(), right.type_name())),
@ -111,12 +118,18 @@ pub fn compute_values(
Ok(UntaggedValue::Primitive(Primitive::Filesize(result)))
}
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Filesize(x / y))),
Operator::Multiply => {
Ok(UntaggedValue::Primitive(Primitive::Filesize(x * *y as u64)))
}
Operator::Divide => {
Ok(UntaggedValue::Primitive(Primitive::Filesize(x / *y as u64)))
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::Int(x), Primitive::Filesize(y)) => match operator {
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Filesize(x * y))),
Operator::Multiply => {
Ok(UntaggedValue::Primitive(Primitive::Filesize(*x as u64 * y)))
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::Int(x), Primitive::Int(y)) => match operator {
@ -126,12 +139,11 @@ pub fn compute_values(
Operator::Divide => {
if y.is_zero() {
Ok(zero_division_error())
} else if x - (y * (x / y)) == num_bigint::BigInt::from(0) {
} else if x - (y * (x / y)) == 0 {
Ok(UntaggedValue::Primitive(Primitive::Int(x / y)))
} else {
Ok(UntaggedValue::Primitive(Primitive::Decimal(
bigdecimal::BigDecimal::from(x.clone())
/ bigdecimal::BigDecimal::from(y.clone()),
bigdecimal::BigDecimal::from(*x) / bigdecimal::BigDecimal::from(*y),
)))
}
}
@ -151,7 +163,176 @@ pub fn compute_values(
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::Int(x), Primitive::BigInt(y)) => match operator {
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::BigInt(
BigInt::from(*x) + y,
))),
Operator::Minus => Ok(UntaggedValue::Primitive(Primitive::BigInt(
BigInt::from(*x) - y,
))),
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::BigInt(
BigInt::from(*x) * y,
))),
Operator::Divide => {
if y.is_zero() {
Ok(zero_division_error())
} else if x - (y * (x / y)) == BigInt::from(0) {
Ok(UntaggedValue::Primitive(Primitive::BigInt(
BigInt::from(*x) / y,
)))
} else {
Ok(UntaggedValue::Primitive(Primitive::Decimal(
bigdecimal::BigDecimal::from(*x)
/ bigdecimal::BigDecimal::from(y.clone()),
)))
}
}
Operator::Modulo => {
if y.is_zero() {
Ok(zero_division_error())
} else {
Ok(UntaggedValue::Primitive(Primitive::BigInt(x % y)))
}
}
Operator::Pow => {
let prim_u32 = ToPrimitive::to_u32(y);
match prim_u32 {
Some(num) => Ok(UntaggedValue::Primitive(Primitive::Int(x.pow(num)))),
_ => Err((left.type_name(), right.type_name())),
}
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::BigInt(x), Primitive::Int(y)) => match operator {
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::BigInt(
x + BigInt::from(*y),
))),
Operator::Minus => Ok(UntaggedValue::Primitive(Primitive::BigInt(
x - BigInt::from(*y),
))),
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::BigInt(
x * BigInt::from(*y),
))),
Operator::Divide => {
if y.is_zero() {
Ok(zero_division_error())
} else if x - (y * (x / y)) == BigInt::from(0) {
Ok(UntaggedValue::Primitive(Primitive::BigInt(
x / BigInt::from(*y),
)))
} else {
Ok(UntaggedValue::Primitive(Primitive::Decimal(
bigdecimal::BigDecimal::from(x.clone())
/ bigdecimal::BigDecimal::from(*y),
)))
}
}
Operator::Modulo => {
if y.is_zero() {
Ok(zero_division_error())
} else {
Ok(UntaggedValue::Primitive(Primitive::BigInt(x % y)))
}
}
Operator::Pow => {
let prim_u32 = ToPrimitive::to_u32(y);
match prim_u32 {
Some(num) => Ok(UntaggedValue::Primitive(Primitive::BigInt(x.pow(num)))),
_ => Err((left.type_name(), right.type_name())),
}
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::BigInt(x), Primitive::BigInt(y)) => match operator {
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::BigInt(x + y))),
Operator::Minus => Ok(UntaggedValue::Primitive(Primitive::BigInt(x - y))),
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::BigInt(x * y))),
Operator::Divide => {
if y.is_zero() {
Ok(zero_division_error())
} else if x - (y * (x / y)) == BigInt::from(0) {
Ok(UntaggedValue::Primitive(Primitive::BigInt(x / y)))
} else {
Ok(UntaggedValue::Primitive(Primitive::Decimal(
bigdecimal::BigDecimal::from(x.clone())
/ bigdecimal::BigDecimal::from(y.clone()),
)))
}
}
Operator::Modulo => {
if y.is_zero() {
Ok(zero_division_error())
} else {
Ok(UntaggedValue::Primitive(Primitive::BigInt(x % y)))
}
}
Operator::Pow => {
let prim_u32 = ToPrimitive::to_u32(y);
match prim_u32 {
Some(num) => Ok(UntaggedValue::Primitive(Primitive::BigInt(x.pow(num)))),
_ => Err((left.type_name(), right.type_name())),
}
}
_ => Err((left.type_name(), right.type_name())),
},
(Primitive::Decimal(x), Primitive::Int(y)) => {
let result = match operator {
Operator::Plus => Ok(x + bigdecimal::BigDecimal::from(*y)),
Operator::Minus => Ok(x - bigdecimal::BigDecimal::from(*y)),
Operator::Multiply => Ok(x * bigdecimal::BigDecimal::from(*y)),
Operator::Divide => {
if y.is_zero() {
return Ok(zero_division_error());
}
Ok(x / bigdecimal::BigDecimal::from(*y))
}
Operator::Modulo => {
if y.is_zero() {
return Ok(zero_division_error());
}
Ok(x % bigdecimal::BigDecimal::from(*y))
}
// leaving this here for the hope that bigdecimal will one day support pow/powf/fpow
// Operator::Pow => {
// let xp = bigdecimal::ToPrimitive::to_f64(x).unwrap_or(0.0);
// let yp = bigdecimal::ToPrimitive::to_f64(y).unwrap_or(0.0);
// let pow = bigdecimal::FromPrimitive::from_f64(xp.powf(yp));
// match pow {
// Some(p) => Ok(p),
// None => Err((left.type_name(), right.type_name())),
// }
// }
_ => Err((left.type_name(), right.type_name())),
}?;
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
}
(Primitive::Int(x), Primitive::Decimal(y)) => {
let result = match operator {
Operator::Plus => Ok(bigdecimal::BigDecimal::from(*x) + y),
Operator::Minus => Ok(bigdecimal::BigDecimal::from(*x) - y),
Operator::Multiply => Ok(bigdecimal::BigDecimal::from(*x) * y),
Operator::Divide => {
if y.is_zero() {
return Ok(zero_division_error());
}
Ok(bigdecimal::BigDecimal::from(*x) / y)
}
Operator::Modulo => {
if y.is_zero() {
return Ok(zero_division_error());
}
Ok(bigdecimal::BigDecimal::from(*x) % y)
}
// big decimal doesn't support pow yet
// Operator::Pow => {
// let yp = bigdecimal::ToPrimitive::to_u32(y).unwrap_or(0);
// Ok(bigdecimal::BigDecimal::from(x.pow(yp)))
// }
_ => Err((left.type_name(), right.type_name())),
}?;
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
}
(Primitive::Decimal(x), Primitive::BigInt(y)) => {
let result = match operator {
Operator::Plus => Ok(x + bigdecimal::BigDecimal::from(y.clone())),
Operator::Minus => Ok(x - bigdecimal::BigDecimal::from(y.clone())),
@ -182,7 +363,7 @@ pub fn compute_values(
}?;
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
}
(Primitive::Int(x), Primitive::Decimal(y)) => {
(Primitive::BigInt(x), Primitive::Decimal(y)) => {
let result = match operator {
Operator::Plus => Ok(bigdecimal::BigDecimal::from(x.clone()) + y),
Operator::Minus => Ok(bigdecimal::BigDecimal::from(x.clone()) - y),