add some float operations with filesize (#6618)

* add some float operations with filesize

* more changes

* update return values on filesize-filesize, duration-duration

* missed filesize in floordiv

* missed float * duration
This commit is contained in:
Darren Schroeder 2022-09-28 17:07:50 -05:00 committed by GitHub
parent 5c99921e15
commit dd578926c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 171 additions and 19 deletions

View file

@ -282,6 +282,66 @@ fn modulo() {
assert_eq!(actual.out, "1");
}
#[test]
fn unit_multiplication_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1mb * 2
"#
));
assert_eq!(actual.out, "1.9 MiB");
}
#[test]
fn unit_multiplication_float_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1mb * 1.2
"#
));
assert_eq!(actual.out, "1.1 MiB");
}
#[test]
fn unit_float_floor_division_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1mb // 3.0
"#
));
assert_eq!(actual.out, "325.5 KiB");
}
#[test]
fn unit_division_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1mb / 4
"#
));
assert_eq!(actual.out, "244.1 KiB");
}
#[test]
fn unit_float_division_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1mb / 3.1
"#
));
assert_eq!(actual.out, "315.0 KiB");
}
#[test]
fn duration_math() {
let actual = nu!(

View file

@ -186,6 +186,7 @@ fn external_arg_with_variable_name() {
})
}
#[cfg(not(windows))]
#[test]
fn external_command_escape_args() {
Playground::setup("external failed command with semicolon", |dirs, _| {

View file

@ -101,11 +101,14 @@ pub fn math_result_type(
(Type::Float, Type::Int) => (Type::Float, None),
(Type::Int, Type::Float) => (Type::Float, None),
(Type::Float, Type::Float) => (Type::Float, None),
(Type::Filesize, Type::Int) => (Type::Filesize, None),
(Type::Int, Type::Filesize) => (Type::Filesize, None),
(Type::Duration, Type::Int) => (Type::Filesize, None),
(Type::Int, Type::Duration) => (Type::Filesize, None),
(Type::Filesize, Type::Float) => (Type::Filesize, None),
(Type::Float, Type::Filesize) => (Type::Filesize, None),
(Type::Duration, Type::Int) => (Type::Duration, None),
(Type::Int, Type::Duration) => (Type::Duration, None),
(Type::Duration, Type::Float) => (Type::Duration, None),
(Type::Float, Type::Duration) => (Type::Duration, None),
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
@ -157,10 +160,11 @@ pub fn math_result_type(
(Type::Int, Type::Float) => (Type::Float, None),
(Type::Float, Type::Float) => (Type::Float, None),
(Type::Filesize, Type::Filesize) => (Type::Float, None),
(Type::Duration, Type::Duration) => (Type::Float, None),
(Type::Filesize, Type::Int) => (Type::Filesize, None),
(Type::Filesize, Type::Float) => (Type::Filesize, None),
(Type::Duration, Type::Duration) => (Type::Float, None),
(Type::Duration, Type::Int) => (Type::Duration, None),
(Type::Duration, Type::Float) => (Type::Duration, None),
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
@ -187,10 +191,11 @@ pub fn math_result_type(
(Type::Int, Type::Float) => (Type::Int, None),
(Type::Float, Type::Float) => (Type::Int, None),
(Type::Filesize, Type::Filesize) => (Type::Int, None),
(Type::Duration, Type::Duration) => (Type::Int, None),
(Type::Filesize, Type::Int) => (Type::Filesize, None),
(Type::Filesize, Type::Float) => (Type::Filesize, None),
(Type::Duration, Type::Duration) => (Type::Int, None),
(Type::Duration, Type::Int) => (Type::Duration, None),
(Type::Duration, Type::Float) => (Type::Duration, None),
(Type::Any, _) => (Type::Any, None),
(_, Type::Any) => (Type::Any, None),

View file

@ -1676,6 +1676,7 @@ impl Value {
}),
}
}
pub fn sub(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
@ -1754,6 +1755,7 @@ impl Value {
}),
}
}
pub fn mul(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
@ -1790,6 +1792,18 @@ impl Value {
span,
})
}
(Value::Float { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => {
Ok(Value::Filesize {
val: (*lhs * *rhs as f64) as i64,
span,
})
}
(Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
Ok(Value::Filesize {
val: (*lhs as f64 * *rhs) as i64,
span,
})
}
(Value::Int { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
Ok(Value::Duration {
val: *lhs * *rhs,
@ -1802,6 +1816,18 @@ impl Value {
span,
})
}
(Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
Ok(Value::Duration {
val: (*lhs as f64 * *rhs) as i64,
span,
})
}
(Value::Float { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
Ok(Value::Duration {
val: (*lhs * *rhs as f64) as i64,
span,
})
}
(Value::CustomValue { val: lhs, span }, rhs) => {
lhs.operation(*span, Operator::Multiply, op, rhs)
}
@ -1815,6 +1841,7 @@ impl Value {
}),
}
}
pub fn div(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
@ -1881,6 +1908,26 @@ impl Value {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if *rhs != 0 {
Ok(Value::Filesize {
val: ((*lhs as f64) / (*rhs as f64)) as i64,
span,
})
} else {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
if *rhs != 0.0 {
Ok(Value::Filesize {
val: (*lhs as f64 / rhs) as i64,
span,
})
} else {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
if *rhs != 0 {
if lhs % rhs == 0 {
@ -1898,20 +1945,20 @@ impl Value {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
(Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if *rhs != 0 {
Ok(Value::Filesize {
val: lhs / rhs,
Ok(Value::Duration {
val: ((*lhs as f64) / (*rhs as f64)) as i64,
span,
})
} else {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if *rhs != 0 {
(Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
if *rhs != 0.0 {
Ok(Value::Duration {
val: lhs / rhs,
val: ((*lhs as f64) / rhs) as i64,
span,
})
} else {
@ -1931,6 +1978,7 @@ impl Value {
}),
}
}
pub fn floor_div(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
@ -1998,6 +2046,32 @@ impl Value {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if *rhs != 0 {
Ok(Value::Filesize {
val: ((*lhs as f64) / (*rhs as f64))
.max(std::i64::MIN as f64)
.min(std::i64::MAX as f64)
.floor() as i64,
span,
})
} else {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
if *rhs != 0.0 {
Ok(Value::Filesize {
val: (*lhs as f64 / *rhs)
.max(std::i64::MIN as f64)
.min(std::i64::MAX as f64)
.floor() as i64,
span,
})
} else {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
if *rhs != 0 {
Ok(Value::Int {
@ -2011,20 +2085,26 @@ impl Value {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
(Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if *rhs != 0 {
Ok(Value::Filesize {
val: lhs / rhs,
Ok(Value::Duration {
val: (*lhs as f64 / *rhs as f64)
.max(std::i64::MIN as f64)
.min(std::i64::MAX as f64)
.floor() as i64,
span,
})
} else {
Err(ShellError::DivisionByZero(op))
}
}
(Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if *rhs != 0 {
(Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
if *rhs != 0.0 {
Ok(Value::Duration {
val: lhs / rhs,
val: (*lhs as f64 / *rhs)
.max(std::i64::MIN as f64)
.min(std::i64::MAX as f64)
.floor() as i64,
span,
})
} else {
@ -2044,6 +2124,7 @@ impl Value {
}),
}
}
pub fn lt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
return lhs.operation(*span, Operator::LessThan, op, rhs);
@ -2070,6 +2151,7 @@ impl Value {
}),
}
}
pub fn lte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
return lhs.operation(*span, Operator::LessThanOrEqual, op, rhs);
@ -2096,6 +2178,7 @@ impl Value {
}),
}
}
pub fn gt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
return lhs.operation(*span, Operator::GreaterThan, op, rhs);
@ -2122,6 +2205,7 @@ impl Value {
}),
}
}
pub fn gte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
return lhs.operation(*span, Operator::GreaterThanOrEqual, op, rhs);
@ -2148,6 +2232,7 @@ impl Value {
}),
}
}
pub fn eq(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
return lhs.operation(*span, Operator::Equal, op, rhs);
@ -2172,6 +2257,7 @@ impl Value {
},
}
}
pub fn ne(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
return lhs.operation(*span, Operator::NotEqual, op, rhs);