mirror of
https://github.com/nushell/nushell.git
synced 2024-11-25 18:03:51 +01:00
Parse integers as BigInt (#2642)
* Parse integer shape as BigInt * Use implicit serde from BigInt crate
This commit is contained in:
parent
93410c470e
commit
a18b2702ca
@ -735,7 +735,7 @@ fn parse_arg(
|
|||||||
|
|
||||||
match expected_type {
|
match expected_type {
|
||||||
SyntaxShape::Number => {
|
SyntaxShape::Number => {
|
||||||
if let Ok(x) = lite_arg.item.parse::<i64>() {
|
if let Ok(x) = lite_arg.item.parse::<BigInt>() {
|
||||||
(
|
(
|
||||||
SpannedExpression::new(Expression::integer(x), lite_arg.span),
|
SpannedExpression::new(Expression::integer(x), lite_arg.span),
|
||||||
None,
|
None,
|
||||||
@ -757,7 +757,7 @@ fn parse_arg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SyntaxShape::Int => {
|
SyntaxShape::Int => {
|
||||||
if let Ok(x) = lite_arg.item.parse::<i64>() {
|
if let Ok(x) = lite_arg.item.parse::<BigInt>() {
|
||||||
(
|
(
|
||||||
SpannedExpression::new(Expression::integer(x), lite_arg.span),
|
SpannedExpression::new(Expression::integer(x), lite_arg.span),
|
||||||
None,
|
None,
|
||||||
@ -945,7 +945,7 @@ mod test {
|
|||||||
let registry = MockRegistry::new();
|
let registry = MockRegistry::new();
|
||||||
let result = parse_arg(SyntaxShape::Int, ®istry, &input);
|
let result = parse_arg(SyntaxShape::Int, ®istry, &input);
|
||||||
assert_eq!(result.1, None);
|
assert_eq!(result.1, None);
|
||||||
assert_eq!(result.0.expr, Expression::integer(32));
|
assert_eq!(result.0.expr, Expression::integer(BigInt::from(32)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,14 +970,24 @@ mod test {
|
|||||||
let registry = MockRegistry::new();
|
let registry = MockRegistry::new();
|
||||||
let result = parse_arg(SyntaxShape::Number, ®istry, &input);
|
let result = parse_arg(SyntaxShape::Number, ®istry, &input);
|
||||||
assert_eq!(result.1, None);
|
assert_eq!(result.1, None);
|
||||||
assert_eq!(result.0.expr, Expression::integer(-34));
|
assert_eq!(result.0.expr, Expression::integer(BigInt::from(-34)));
|
||||||
|
|
||||||
let raw = "34".to_string();
|
let raw = "34".to_string();
|
||||||
let input = raw.clone().spanned(Span::new(0, raw.len()));
|
let input = raw.clone().spanned(Span::new(0, raw.len()));
|
||||||
let registry = MockRegistry::new();
|
let registry = MockRegistry::new();
|
||||||
let result = parse_arg(SyntaxShape::Number, ®istry, &input);
|
let result = parse_arg(SyntaxShape::Number, ®istry, &input);
|
||||||
assert_eq!(result.1, None);
|
assert_eq!(result.1, None);
|
||||||
assert_eq!(result.0.expr, Expression::integer(34));
|
assert_eq!(result.0.expr, Expression::integer(BigInt::from(34)));
|
||||||
|
|
||||||
|
let raw = "36893488147419103232".to_string();
|
||||||
|
let input = raw.clone().spanned(Span::new(0, raw.len()));
|
||||||
|
let registry = MockRegistry::new();
|
||||||
|
let result = parse_arg(SyntaxShape::Number, ®istry, &input);
|
||||||
|
assert_eq!(result.1, None);
|
||||||
|
assert_eq!(
|
||||||
|
result.0.expr,
|
||||||
|
Expression::integer(BigInt::from(36893488147419103232 as u128))
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1095,8 +1095,8 @@ impl IntoSpanned for Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn integer(i: i64) -> Expression {
|
pub fn integer(i: BigInt) -> Expression {
|
||||||
Expression::Literal(Literal::Number(Number::Int(BigInt::from(i))))
|
Expression::Literal(Literal::Number(Number::Int(i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decimal(f: f64) -> Result<Expression, ParseError> {
|
pub fn decimal(f: f64) -> Result<Expression, ParseError> {
|
||||||
|
@ -8,7 +8,6 @@ pub mod iter;
|
|||||||
pub mod primitive;
|
pub mod primitive;
|
||||||
pub mod range;
|
pub mod range;
|
||||||
mod serde_bigdecimal;
|
mod serde_bigdecimal;
|
||||||
mod serde_bigint;
|
|
||||||
|
|
||||||
use crate::hir;
|
use crate::hir;
|
||||||
use crate::type_name::{ShellTypeName, SpannedTypeName};
|
use crate::type_name::{ShellTypeName, SpannedTypeName};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::type_name::ShellTypeName;
|
use crate::type_name::ShellTypeName;
|
||||||
use crate::value::column_path::ColumnPath;
|
use crate::value::column_path::ColumnPath;
|
||||||
use crate::value::range::{Range, RangeInclusion};
|
use crate::value::range::{Range, RangeInclusion};
|
||||||
use crate::value::{serde_bigdecimal, serde_bigint};
|
use crate::value::serde_bigdecimal;
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use nu_errors::{ExpectedRange, ShellError};
|
use nu_errors::{ExpectedRange, ShellError};
|
||||||
@ -25,7 +25,6 @@ pub enum Primitive {
|
|||||||
/// An empty value
|
/// An empty value
|
||||||
Nothing,
|
Nothing,
|
||||||
/// A "big int", an integer with arbitrarily large size (aka not limited to 64-bit)
|
/// A "big int", an integer with arbitrarily large size (aka not limited to 64-bit)
|
||||||
#[serde(with = "serde_bigint")]
|
|
||||||
Int(BigInt),
|
Int(BigInt),
|
||||||
/// A "big decimal", an decimal number with arbitrarily large size (aka not limited to 64-bit)
|
/// A "big decimal", an decimal number with arbitrarily large size (aka not limited to 64-bit)
|
||||||
#[serde(with = "serde_bigdecimal")]
|
#[serde(with = "serde_bigdecimal")]
|
||||||
@ -45,7 +44,6 @@ pub enum Primitive {
|
|||||||
/// A date value, in UTC
|
/// A date value, in UTC
|
||||||
Date(DateTime<Utc>),
|
Date(DateTime<Utc>),
|
||||||
/// A count in the number of nanoseconds
|
/// A count in the number of nanoseconds
|
||||||
#[serde(with = "serde_bigint")]
|
|
||||||
Duration(BigInt),
|
Duration(BigInt),
|
||||||
/// A range of values
|
/// A range of values
|
||||||
Range(Box<Range>),
|
Range(Box<Range>),
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
use num_bigint::BigInt;
|
|
||||||
use num_traits::cast::FromPrimitive;
|
|
||||||
use num_traits::cast::ToPrimitive;
|
|
||||||
|
|
||||||
/// Enable big int serialization by providing a `serialize` function
|
|
||||||
pub fn serialize<S>(big_int: &BigInt, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
serde::Serialize::serialize(
|
|
||||||
&big_int
|
|
||||||
.to_i64()
|
|
||||||
.ok_or_else(|| serde::ser::Error::custom("expected a i64-sized bignum"))?,
|
|
||||||
serializer,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable big int deserialization by providing a `deserialize` function
|
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<BigInt, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let x: i64 = serde::Deserialize::deserialize(deserializer)?;
|
|
||||||
Ok(BigInt::from_i64(x)
|
|
||||||
.ok_or_else(|| serde::de::Error::custom("expected a i64-sized bignum"))?)
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user