mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 00:13:21 +01:00
Change append operator to concat operator
This commit is contained in:
parent
30f98f7e64
commit
e987ccab56
@ -60,10 +60,6 @@ impl Completer for OperatorCompletion {
|
||||
("bit-shr", "Bitwise shift right"),
|
||||
("in", "Is a member of (doesn't use regex)"),
|
||||
("not-in", "Is not a member of (doesn't use regex)"),
|
||||
(
|
||||
"++",
|
||||
"Appends two lists, a list and a value, two strings, or two binary values",
|
||||
),
|
||||
],
|
||||
Expr::String(_) => vec![
|
||||
("=~", "Contains regex match"),
|
||||
@ -72,7 +68,7 @@ impl Completer for OperatorCompletion {
|
||||
("not-like", "Does not contain regex match"),
|
||||
(
|
||||
"++",
|
||||
"Appends two lists, a list and a value, two strings, or two binary values",
|
||||
"Concatenates two lists, two strings, or two binary values",
|
||||
),
|
||||
("in", "Is a member of (doesn't use regex)"),
|
||||
("not-in", "Is not a member of (doesn't use regex)"),
|
||||
@ -95,10 +91,6 @@ impl Completer for OperatorCompletion {
|
||||
("**", "Power of"),
|
||||
("in", "Is a member of (doesn't use regex)"),
|
||||
("not-in", "Is not a member of (doesn't use regex)"),
|
||||
(
|
||||
"++",
|
||||
"Appends two lists, a list and a value, two strings, or two binary values",
|
||||
),
|
||||
],
|
||||
Expr::Bool(_) => vec![
|
||||
(
|
||||
@ -113,15 +105,11 @@ impl Completer for OperatorCompletion {
|
||||
("not", "Negates a value or expression"),
|
||||
("in", "Is a member of (doesn't use regex)"),
|
||||
("not-in", "Is not a member of (doesn't use regex)"),
|
||||
(
|
||||
"++",
|
||||
"Appends two lists, a list and a value, two strings, or two binary values",
|
||||
),
|
||||
],
|
||||
Expr::FullCellPath(path) => match path.head.expr {
|
||||
Expr::List(_) => vec![(
|
||||
"++",
|
||||
"Appends two lists, a list and a value, two strings, or two binary values",
|
||||
"Concatenates two lists, two strings, or two binary values",
|
||||
)],
|
||||
Expr::Var(id) => get_variable_completions(id, working_set),
|
||||
_ => vec![],
|
||||
@ -165,7 +153,7 @@ pub fn get_variable_completions<'a>(
|
||||
Type::List(_) | Type::String | Type::Binary => vec![
|
||||
(
|
||||
"++=",
|
||||
"Appends a list, a value, a string, or a binary value to a variable.",
|
||||
"Concatenates two lists, two strings, or two binary values",
|
||||
),
|
||||
("=", "Assigns a value to a variable."),
|
||||
],
|
||||
|
@ -31,7 +31,7 @@ impl Command for HelpOperators {
|
||||
let mut operators = [
|
||||
Operator::Assignment(Assignment::Assign),
|
||||
Operator::Assignment(Assignment::PlusAssign),
|
||||
Operator::Assignment(Assignment::AppendAssign),
|
||||
Operator::Assignment(Assignment::ConcatAssign),
|
||||
Operator::Assignment(Assignment::MinusAssign),
|
||||
Operator::Assignment(Assignment::MultiplyAssign),
|
||||
Operator::Assignment(Assignment::DivideAssign),
|
||||
@ -48,7 +48,7 @@ impl Command for HelpOperators {
|
||||
Operator::Comparison(Comparison::StartsWith),
|
||||
Operator::Comparison(Comparison::EndsWith),
|
||||
Operator::Math(Math::Plus),
|
||||
Operator::Math(Math::Append),
|
||||
Operator::Math(Math::Concat),
|
||||
Operator::Math(Math::Minus),
|
||||
Operator::Math(Math::Multiply),
|
||||
Operator::Math(Math::Divide),
|
||||
@ -144,7 +144,7 @@ fn description(operator: &Operator) -> &'static str {
|
||||
Operator::Comparison(Comparison::StartsWith) => "Checks if a string starts with another.",
|
||||
Operator::Comparison(Comparison::EndsWith) => "Checks if a string ends with another.",
|
||||
Operator::Math(Math::Plus) => "Adds two values.",
|
||||
Operator::Math(Math::Append) => {
|
||||
Operator::Math(Math::Concat) => {
|
||||
"Appends two lists, a list and a value, two strings, or two binary values."
|
||||
}
|
||||
Operator::Math(Math::Minus) => "Subtracts two values.",
|
||||
@ -163,7 +163,7 @@ fn description(operator: &Operator) -> &'static str {
|
||||
Operator::Bits(Bits::ShiftRight) => "Bitwise shifts a value right by another.",
|
||||
Operator::Assignment(Assignment::Assign) => "Assigns a value to a variable.",
|
||||
Operator::Assignment(Assignment::PlusAssign) => "Adds a value to a variable.",
|
||||
Operator::Assignment(Assignment::AppendAssign) => {
|
||||
Operator::Assignment(Assignment::ConcatAssign) => {
|
||||
"Appends a list, a value, a string, or a binary value to a variable."
|
||||
}
|
||||
Operator::Assignment(Assignment::MinusAssign) => "Subtracts a value from a variable.",
|
||||
|
@ -1,88 +0,0 @@
|
||||
use nu_test_support::nu;
|
||||
|
||||
#[test]
|
||||
fn append_assign_int() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [1 2];
|
||||
$a ++= [3 4];
|
||||
$a == [1 2 3 4]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_string() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [a b];
|
||||
$a ++= [c d];
|
||||
$a == [a b c d]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_any() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [1 2 a];
|
||||
$a ++= [b 3];
|
||||
$a == [1 2 a b 3]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_both_empty() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [];
|
||||
$a ++= [];
|
||||
$a == []
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_type_mismatch() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [1 2];
|
||||
$a ++= [a];
|
||||
$a == [1 2 "a"]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_single_element() {
|
||||
let actual = nu!(r#"
|
||||
mut a = ["list" "and"];
|
||||
$a ++= "a single element";
|
||||
$a == ["list" "and" "a single element"]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_to_single_element() {
|
||||
let actual = nu!(r#"
|
||||
mut a = "string";
|
||||
$a ++= ["and" "the" "list"];
|
||||
$a == ["string" "and" "the" "list"]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_assign_single_to_single() {
|
||||
let actual = nu!(r#"
|
||||
mut a = 1;
|
||||
$a ++= "and a single element";
|
||||
"#);
|
||||
|
||||
assert!(actual.err.contains("nu::parser::unsupported_operation"));
|
||||
}
|
76
crates/nu-command/tests/commands/assignment/concat.rs
Normal file
76
crates/nu-command/tests/commands/assignment/concat.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use nu_test_support::nu;
|
||||
|
||||
#[test]
|
||||
fn concat_assign_list_int() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [1 2];
|
||||
$a ++= [3 4];
|
||||
$a == [1 2 3 4]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_assign_list_string() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [a b];
|
||||
$a ++= [c d];
|
||||
$a == [a b c d]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_assign_any() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [1 2 a];
|
||||
$a ++= [b 3];
|
||||
$a == [1 2 a b 3]
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_assign_both_empty() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [];
|
||||
$a ++= [];
|
||||
$a == []
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_assign_string() {
|
||||
let actual = nu!(r#"
|
||||
mut a = 'hello';
|
||||
$a ++= ' world';
|
||||
$a == 'hello world'
|
||||
"#);
|
||||
|
||||
assert_eq!(actual.out, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_assign_type_mismatch() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [];
|
||||
$a ++= 'str'
|
||||
"#);
|
||||
|
||||
assert!(actual.err.contains("nu::parser::unsupported_operation"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_assign_runtime_type_mismatch() {
|
||||
let actual = nu!(r#"
|
||||
mut a = [];
|
||||
$a ++= if true { 'str' }
|
||||
"#);
|
||||
|
||||
assert!(actual.err.contains("nu::shell::type_mismatch"));
|
||||
}
|
@ -1 +1 @@
|
||||
mod append_assign;
|
||||
mod concat;
|
||||
|
@ -483,7 +483,7 @@ fn compound_where_paren() {
|
||||
// TODO: these ++ tests are not really testing *math* functionality, maybe find another place for them
|
||||
|
||||
#[test]
|
||||
fn adding_lists() {
|
||||
fn concat_lists() {
|
||||
let actual = nu!(pipeline(
|
||||
r#"
|
||||
[1 3] ++ [5 6] | to nuon
|
||||
@ -494,29 +494,7 @@ fn adding_lists() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_list_and_value() {
|
||||
let actual = nu!(pipeline(
|
||||
r#"
|
||||
[1 3] ++ 5 | to nuon
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "[1, 3, 5]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_value_and_list() {
|
||||
let actual = nu!(pipeline(
|
||||
r#"
|
||||
1 ++ [3 5] | to nuon
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "[1, 3, 5]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_tables() {
|
||||
fn concat_tables() {
|
||||
let actual = nu!(pipeline(
|
||||
r#"
|
||||
[[a b]; [1 2]] ++ [[c d]; [10 11]] | to nuon
|
||||
@ -526,7 +504,7 @@ fn adding_tables() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_strings() {
|
||||
fn concat_strings() {
|
||||
let actual = nu!(pipeline(
|
||||
r#"
|
||||
"foo" ++ "bar"
|
||||
@ -536,7 +514,7 @@ fn append_strings() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_binary_values() {
|
||||
fn concat_binary_values() {
|
||||
let actual = nu!(pipeline(
|
||||
r#"
|
||||
0x[01 02] ++ 0x[03 04] | to nuon
|
||||
|
@ -27,7 +27,7 @@ fn url_join_with_only_user() {
|
||||
"password": "",
|
||||
"host": "localhost",
|
||||
"port": "",
|
||||
} | url join
|
||||
} | url join
|
||||
"#
|
||||
));
|
||||
|
||||
@ -44,7 +44,7 @@ fn url_join_with_only_pwd() {
|
||||
"password": "pwd",
|
||||
"host": "localhost",
|
||||
"port": "",
|
||||
} | url join
|
||||
} | url join
|
||||
"#
|
||||
));
|
||||
|
||||
@ -61,7 +61,7 @@ fn url_join_with_user_and_pwd() {
|
||||
"password": "pwd",
|
||||
"host": "localhost",
|
||||
"port": "",
|
||||
} | url join
|
||||
} | url join
|
||||
"#
|
||||
));
|
||||
|
||||
@ -79,7 +79,7 @@ fn url_join_with_query() {
|
||||
"host": "localhost",
|
||||
"query": "par_1=aaa&par_2=bbb"
|
||||
"port": "",
|
||||
} | url join
|
||||
} | url join
|
||||
"#
|
||||
));
|
||||
|
||||
@ -411,12 +411,9 @@ fn url_join_with_params_invalid_table() {
|
||||
"host": "localhost",
|
||||
"params": (
|
||||
[
|
||||
["key", "value"];
|
||||
["par_1", "aaa"],
|
||||
["par_2", "bbb"],
|
||||
["par_1", "ccc"],
|
||||
["par_2", "ddd"],
|
||||
] ++ ["not a record"]
|
||||
{ key: foo, value: bar }
|
||||
"not a record"
|
||||
]
|
||||
),
|
||||
"port": "1234",
|
||||
} | url join
|
||||
|
@ -155,7 +155,7 @@ pub(crate) fn decompose_assignment(assignment: Assignment) -> Option<Operator> {
|
||||
match assignment {
|
||||
Assignment::Assign => None,
|
||||
Assignment::PlusAssign => Some(Operator::Math(Math::Plus)),
|
||||
Assignment::AppendAssign => Some(Operator::Math(Math::Append)),
|
||||
Assignment::ConcatAssign => Some(Operator::Math(Math::Concat)),
|
||||
Assignment::MinusAssign => Some(Operator::Math(Math::Minus)),
|
||||
Assignment::MultiplyAssign => Some(Operator::Math(Math::Multiply)),
|
||||
Assignment::DivideAssign => Some(Operator::Math(Math::Divide)),
|
||||
|
@ -794,9 +794,9 @@ impl Eval for EvalRuntime {
|
||||
let lhs = eval_expression::<D>(engine_state, stack, lhs)?;
|
||||
lhs.div(op_span, &rhs, op_span)?
|
||||
}
|
||||
Assignment::AppendAssign => {
|
||||
Assignment::ConcatAssign => {
|
||||
let lhs = eval_expression::<D>(engine_state, stack, lhs)?;
|
||||
lhs.append(op_span, &rhs, op_span)?
|
||||
lhs.concat(op_span, &rhs, op_span)?
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -956,7 +956,7 @@ fn binary_op(
|
||||
},
|
||||
Operator::Math(mat) => match mat {
|
||||
Math::Plus => lhs_val.add(op_span, &rhs_val, span)?,
|
||||
Math::Append => lhs_val.append(op_span, &rhs_val, span)?,
|
||||
Math::Concat => lhs_val.concat(op_span, &rhs_val, span)?,
|
||||
Math::Minus => lhs_val.sub(op_span, &rhs_val, span)?,
|
||||
Math::Multiply => lhs_val.mul(op_span, &rhs_val, span)?,
|
||||
Math::Divide => lhs_val.div(op_span, &rhs_val, span)?,
|
||||
|
@ -4895,7 +4895,7 @@ pub fn parse_assignment_operator(working_set: &mut StateWorkingSet, span: Span)
|
||||
let operator = match contents {
|
||||
b"=" => Operator::Assignment(Assignment::Assign),
|
||||
b"+=" => Operator::Assignment(Assignment::PlusAssign),
|
||||
b"++=" => Operator::Assignment(Assignment::AppendAssign),
|
||||
b"++=" => Operator::Assignment(Assignment::ConcatAssign),
|
||||
b"-=" => Operator::Assignment(Assignment::MinusAssign),
|
||||
b"*=" => Operator::Assignment(Assignment::MultiplyAssign),
|
||||
b"/=" => Operator::Assignment(Assignment::DivideAssign),
|
||||
@ -5021,7 +5021,7 @@ pub fn parse_operator(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
||||
b"=~" | b"like" => Operator::Comparison(Comparison::RegexMatch),
|
||||
b"!~" | b"not-like" => Operator::Comparison(Comparison::NotRegexMatch),
|
||||
b"+" => Operator::Math(Math::Plus),
|
||||
b"++" => Operator::Math(Math::Append),
|
||||
b"++" => Operator::Math(Math::Concat),
|
||||
b"-" => Operator::Math(Math::Minus),
|
||||
b"*" => Operator::Math(Math::Multiply),
|
||||
b"/" => Operator::Math(Math::Divide),
|
||||
|
@ -131,7 +131,7 @@ pub fn math_result_type(
|
||||
)
|
||||
}
|
||||
},
|
||||
Operator::Math(Math::Append) => check_append(working_set, lhs, rhs, op),
|
||||
Operator::Math(Math::Concat) => check_concat(working_set, lhs, rhs, op),
|
||||
Operator::Math(Math::Minus) => match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Int, Type::Int) => (Type::Int, None),
|
||||
(Type::Float, Type::Int) => (Type::Float, None),
|
||||
@ -934,8 +934,8 @@ pub fn math_result_type(
|
||||
)
|
||||
}
|
||||
},
|
||||
Operator::Assignment(Assignment::AppendAssign) => {
|
||||
check_append(working_set, lhs, rhs, op)
|
||||
Operator::Assignment(Assignment::ConcatAssign) => {
|
||||
check_concat(working_set, lhs, rhs, op)
|
||||
}
|
||||
Operator::Assignment(_) => match (&lhs.ty, &rhs.ty) {
|
||||
(x, y) if x == y => (Type::Nothing, None),
|
||||
@ -1084,7 +1084,7 @@ pub fn check_block_input_output(working_set: &StateWorkingSet, block: &Block) ->
|
||||
output_errors
|
||||
}
|
||||
|
||||
fn check_append(
|
||||
fn check_concat(
|
||||
working_set: &mut StateWorkingSet,
|
||||
lhs: &Expression,
|
||||
rhs: &Expression,
|
||||
@ -1098,13 +1098,6 @@ fn check_append(
|
||||
(Type::List(Box::new(Type::Any)), None)
|
||||
}
|
||||
}
|
||||
(Type::List(a), b) | (b, Type::List(a)) => {
|
||||
if a == &Box::new(b.clone()) {
|
||||
(Type::List(a.clone()), None)
|
||||
} else {
|
||||
(Type::List(Box::new(Type::Any)), None)
|
||||
}
|
||||
}
|
||||
(Type::Table(a), Type::Table(_)) => (Type::Table(a.clone()), None),
|
||||
(Type::String, Type::String) => (Type::String, None),
|
||||
(Type::Binary, Type::Binary) => (Type::Binary, None),
|
||||
@ -1114,7 +1107,7 @@ fn check_append(
|
||||
(
|
||||
Type::Any,
|
||||
Some(ParseError::UnsupportedOperationRHS(
|
||||
"append".into(),
|
||||
"concat".into(),
|
||||
op.span,
|
||||
lhs.span,
|
||||
lhs.ty.clone(),
|
||||
@ -1128,7 +1121,7 @@ fn check_append(
|
||||
(
|
||||
Type::Any,
|
||||
Some(ParseError::UnsupportedOperationLHS(
|
||||
"append".into(),
|
||||
"concat".into(),
|
||||
op.span,
|
||||
lhs.span,
|
||||
lhs.ty.clone(),
|
||||
|
@ -1485,7 +1485,7 @@ fn prepare_plugin_call_custom_value_op() {
|
||||
span,
|
||||
},
|
||||
CustomValueOp::Operation(
|
||||
Operator::Math(Math::Append).into_spanned(span),
|
||||
Operator::Math(Math::Concat).into_spanned(span),
|
||||
cv_ok_val.clone(),
|
||||
),
|
||||
),
|
||||
@ -1498,7 +1498,7 @@ fn prepare_plugin_call_custom_value_op() {
|
||||
span,
|
||||
},
|
||||
CustomValueOp::Operation(
|
||||
Operator::Math(Math::Append).into_spanned(span),
|
||||
Operator::Math(Math::Concat).into_spanned(span),
|
||||
cv_bad_val.clone(),
|
||||
),
|
||||
),
|
||||
|
@ -24,7 +24,7 @@ pub enum Comparison {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Math {
|
||||
Plus,
|
||||
Append,
|
||||
Concat,
|
||||
Minus,
|
||||
Multiply,
|
||||
Divide,
|
||||
@ -53,7 +53,7 @@ pub enum Bits {
|
||||
pub enum Assignment {
|
||||
Assign,
|
||||
PlusAssign,
|
||||
AppendAssign,
|
||||
ConcatAssign,
|
||||
MinusAssign,
|
||||
MultiplyAssign,
|
||||
DivideAssign,
|
||||
@ -90,7 +90,7 @@ impl Operator {
|
||||
| Self::Comparison(Comparison::NotEqual)
|
||||
| Self::Comparison(Comparison::In)
|
||||
| Self::Comparison(Comparison::NotIn)
|
||||
| Self::Math(Math::Append) => 80,
|
||||
| Self::Math(Math::Concat) => 80,
|
||||
Self::Bits(Bits::BitAnd) => 75,
|
||||
Self::Bits(Bits::BitXor) => 70,
|
||||
Self::Bits(Bits::BitOr) => 60,
|
||||
@ -107,7 +107,7 @@ impl Display for Operator {
|
||||
match self {
|
||||
Operator::Assignment(Assignment::Assign) => write!(f, "="),
|
||||
Operator::Assignment(Assignment::PlusAssign) => write!(f, "+="),
|
||||
Operator::Assignment(Assignment::AppendAssign) => write!(f, "++="),
|
||||
Operator::Assignment(Assignment::ConcatAssign) => write!(f, "++="),
|
||||
Operator::Assignment(Assignment::MinusAssign) => write!(f, "-="),
|
||||
Operator::Assignment(Assignment::MultiplyAssign) => write!(f, "*="),
|
||||
Operator::Assignment(Assignment::DivideAssign) => write!(f, "/="),
|
||||
@ -124,7 +124,7 @@ impl Display for Operator {
|
||||
Operator::Comparison(Comparison::In) => write!(f, "in"),
|
||||
Operator::Comparison(Comparison::NotIn) => write!(f, "not-in"),
|
||||
Operator::Math(Math::Plus) => write!(f, "+"),
|
||||
Operator::Math(Math::Append) => write!(f, "++"),
|
||||
Operator::Math(Math::Concat) => write!(f, "++"),
|
||||
Operator::Math(Math::Minus) => write!(f, "-"),
|
||||
Operator::Math(Math::Multiply) => write!(f, "*"),
|
||||
Operator::Math(Math::Divide) => write!(f, "/"),
|
||||
|
@ -238,7 +238,7 @@ pub trait Eval {
|
||||
Math::Minus => lhs.sub(op_span, &rhs, expr_span),
|
||||
Math::Multiply => lhs.mul(op_span, &rhs, expr_span),
|
||||
Math::Divide => lhs.div(op_span, &rhs, expr_span),
|
||||
Math::Append => lhs.append(op_span, &rhs, expr_span),
|
||||
Math::Concat => lhs.concat(op_span, &rhs, expr_span),
|
||||
Math::Modulo => lhs.modulo(op_span, &rhs, expr_span),
|
||||
Math::FloorDivision => lhs.floor_div(op_span, &rhs, expr_span),
|
||||
Math::Pow => lhs.pow(op_span, &rhs, expr_span),
|
||||
|
@ -2492,34 +2492,20 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
pub fn concat(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::List { vals: lhs, .. }, Value::List { vals: rhs, .. }) => {
|
||||
let mut lhs = lhs.clone();
|
||||
let mut rhs = rhs.clone();
|
||||
lhs.append(&mut rhs);
|
||||
Ok(Value::list(lhs, span))
|
||||
}
|
||||
(Value::List { vals: lhs, .. }, val) => {
|
||||
let mut lhs = lhs.clone();
|
||||
lhs.push(val.clone());
|
||||
Ok(Value::list(lhs, span))
|
||||
}
|
||||
(val, Value::List { vals: rhs, .. }) => {
|
||||
let mut rhs = rhs.clone();
|
||||
rhs.insert(0, val.clone());
|
||||
Ok(Value::list(rhs, span))
|
||||
Ok(Value::list([lhs.as_slice(), rhs.as_slice()].concat(), span))
|
||||
}
|
||||
(Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => {
|
||||
Ok(Value::string(lhs.to_string() + rhs, span))
|
||||
}
|
||||
(Value::Binary { val: lhs, .. }, Value::Binary { val: rhs, .. }) => {
|
||||
let mut val = lhs.clone();
|
||||
val.extend(rhs);
|
||||
Ok(Value::binary(val, span))
|
||||
Ok(Value::string([lhs.as_str(), rhs.as_str()].join(""), span))
|
||||
}
|
||||
(Value::Binary { val: lhs, .. }, Value::Binary { val: rhs, .. }) => Ok(Value::binary(
|
||||
[lhs.as_slice(), rhs.as_slice()].concat(),
|
||||
span,
|
||||
)),
|
||||
(Value::Custom { val: lhs, .. }, rhs) => {
|
||||
lhs.operation(self.span(), Operator::Math(Math::Append), op, rhs)
|
||||
lhs.operation(self.span(), Operator::Math(Math::Concat), op, rhs)
|
||||
}
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
|
@ -37,7 +37,7 @@ def get-all-operators [] { return [
|
||||
|
||||
[Assignment, =, Assign, "Assigns a value to a variable.", 10]
|
||||
[Assignment, +=, PlusAssign, "Adds a value to a variable.", 10]
|
||||
[Assignment, ++=, AppendAssign, "Appends a list or a value to a variable.", 10]
|
||||
[Assignment, ++=, ConcatAssign, "Concatenate two lists, two strings, or two binary values.", 10]
|
||||
[Assignment, -=, MinusAssign, "Subtracts a value from a variable.", 10]
|
||||
[Assignment, *=, MultiplyAssign, "Multiplies a variable by a value.", 10]
|
||||
[Assignment, /=, DivideAssign, "Divides a variable by a value.", 10]
|
||||
@ -55,7 +55,7 @@ def get-all-operators [] { return [
|
||||
[Comparison, ends-with, EndsWith, "Checks if a string ends with another.", 80]
|
||||
[Comparison, not, UnaryNot, "Negates a value or expression.", 0]
|
||||
[Math, +, Plus, "Adds two values.", 90]
|
||||
[Math, ++, Append, "Appends two lists or a list and a value.", 80]
|
||||
[Math, ++, Concat, "Concatenate two lists, two strings, or two binary values.", 80]
|
||||
[Math, -, Minus, "Subtracts two values.", 90]
|
||||
[Math, *, Multiply, "Multiplies two values.", 95]
|
||||
[Math, /, Divide, "Divides two values.", 95]
|
||||
|
@ -112,7 +112,7 @@ impl CustomValue for CoolCustomValue {
|
||||
) -> Result<Value, ShellError> {
|
||||
match operator {
|
||||
// Append the string inside `cool`
|
||||
ast::Operator::Math(ast::Math::Append) => {
|
||||
ast::Operator::Math(ast::Math::Concat) => {
|
||||
if let Some(right) = right
|
||||
.as_custom_value()
|
||||
.ok()
|
||||
|
@ -154,7 +154,6 @@ fn const_unary_operator(#[case] inp: &[&str], #[case] expect: &str) {
|
||||
#[case(&[r#"const x = "a" ++ "b" "#, "$x"], "ab")]
|
||||
#[case(&[r#"const x = [1,2] ++ [3]"#, "$x | describe"], "list<int>")]
|
||||
#[case(&[r#"const x = 0x[1,2] ++ 0x[3]"#, "$x | describe"], "binary")]
|
||||
#[case(&[r#"const x = 0x[1,2] ++ [3]"#, "$x | describe"], "list<any>")]
|
||||
#[case(&["const x = 1 < 2", "$x"], "true")]
|
||||
#[case(&["const x = (3 * 200) > (2 * 100)", "$x"], "true")]
|
||||
#[case(&["const x = (3 * 200) < (2 * 100)", "$x"], "false")]
|
||||
|
@ -187,7 +187,7 @@ fn record_spread() {
|
||||
#[test]
|
||||
fn binary_op_example() {
|
||||
test_eval(
|
||||
"(([1 2] ++ [3 4]) == [1 2 3 4]) and (([1 2 3] ++ 4) == ([1] ++ [2 3 4]))",
|
||||
"(([1 2] ++ [3 4]) == [1 2 3 4]) and (([1] ++ [2 3 4]) == [1 2 3 4])",
|
||||
Eq("true"),
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user