diff --git a/crates/nu-command/tests/commands/math/mod.rs b/crates/nu-command/tests/commands/math/mod.rs index e8fc3ae106..fd03b7109d 100644 --- a/crates/nu-command/tests/commands/math/mod.rs +++ b/crates/nu-command/tests/commands/math/mod.rs @@ -543,3 +543,31 @@ fn append_binary_values() { )); assert_eq!(actual.out, "0x[01020304]"); } + +#[test] +fn int_multiple_string() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#"3 * "ab""# + )); + assert_eq!(actual.out, "ababab"); + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#""ab" * 3"# + )); + assert_eq!(actual.out, "ababab"); +} + +#[test] +fn int_multiple_list() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#"3 * [1 2] | to nuon"# + )); + assert_eq!(actual.out, "[1, 2, 1, 2, 1, 2]"); + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#"[1 2] * 3 | to nuon"# + )); + assert_eq!(actual.out, "[1, 2, 1, 2, 1, 2]"); +} diff --git a/crates/nu-parser/src/type_check.rs b/crates/nu-parser/src/type_check.rs index 93e9dbde71..2d5ef6fbad 100644 --- a/crates/nu-parser/src/type_check.rs +++ b/crates/nu-parser/src/type_check.rs @@ -142,6 +142,10 @@ pub fn math_result_type( (Type::Int, Type::Duration) => (Type::Duration, None), (Type::Duration, Type::Float) => (Type::Duration, None), (Type::Float, Type::Duration) => (Type::Duration, None), + (Type::Int, Type::String) => (Type::String, None), + (Type::String, Type::Int) => (Type::String, None), + (Type::Int, Type::List(a)) => (Type::List(a.clone()), None), + (Type::List(a), Type::Int) => (Type::List(a.clone()), 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), diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 300c2c16b2..d39be76daf 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -2264,7 +2264,34 @@ impl Value { (Value::CustomValue { val: lhs, span }, rhs) => { lhs.operation(*span, Operator::Math(Math::Multiply), op, rhs) } - + (Value::Int { val: lhs, .. }, Value::String { val: rhs, .. }) => { + let mut res = String::new(); + for _ in 0..*lhs { + res.push_str(rhs) + } + Ok(Value::String { val: res, span }) + } + (Value::String { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + let mut res = String::new(); + for _ in 0..*rhs { + res.push_str(lhs) + } + Ok(Value::String { val: res, span }) + } + (Value::Int { val: lhs, .. }, Value::List { vals: rhs, .. }) => { + let mut res = vec![]; + for _ in 0..*lhs { + res.append(&mut rhs.clone()) + } + Ok(Value::List { vals: res, span }) + } + (Value::List { vals: lhs, .. }, Value::Int { val: rhs, .. }) => { + let mut res = vec![]; + for _ in 0..*rhs { + res.append(&mut lhs.clone()) + } + Ok(Value::List { vals: res, span }) + } _ => Err(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type(),