mirror of
https://github.com/nushell/nushell.git
synced 2025-01-22 06:08:47 +01:00
make ++
append lists (#6766)
* make `++` append lists * fmt * fix for database
This commit is contained in:
parent
50e53e788a
commit
5e748ae8fc
@ -124,7 +124,8 @@ impl CustomValue for ExprDb {
|
||||
| Operator::ShiftLeft
|
||||
| Operator::ShiftRight
|
||||
| Operator::StartsWith
|
||||
| Operator::EndsWith => Err(ShellError::UnsupportedOperator(operator, op)),
|
||||
| Operator::EndsWith
|
||||
| Operator::Append => Err(ShellError::UnsupportedOperator(operator, op)),
|
||||
}?;
|
||||
|
||||
let expr = Expr::BinaryOp {
|
||||
|
@ -473,3 +473,39 @@ fn compound_where_paren() {
|
||||
|
||||
assert_eq!(actual.out, r#"[{"a": 2,"b": 1},{"a": 2,"b": 2}]"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_lists() {
|
||||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
[1 3] ++ [5 6] | to nuon
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "[1, 3, 5, 6]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_list_and_value() {
|
||||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
[1 3] ++ 5 | to nuon
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "[1, 3, 5]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adding_value_and_list() {
|
||||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
1 ++ [3 5] | to nuon
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "[1, 3, 5]");
|
||||
}
|
||||
|
@ -385,6 +385,10 @@ pub fn eval_expression(
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
lhs.add(op_span, &rhs, expr.span)
|
||||
}
|
||||
Operator::Append => {
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
lhs.append(op_span, &rhs, expr.span)
|
||||
}
|
||||
Operator::Minus => {
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
lhs.sub(op_span, &rhs, expr.span)
|
||||
|
@ -4273,6 +4273,7 @@ pub fn parse_operator(
|
||||
b"=~" => Operator::RegexMatch,
|
||||
b"!~" => Operator::NotRegexMatch,
|
||||
b"+" => Operator::Plus,
|
||||
b"++" => Operator::Append,
|
||||
b"-" => Operator::Minus,
|
||||
b"*" => Operator::Multiply,
|
||||
b"/" => Operator::Divide,
|
||||
|
@ -68,6 +68,35 @@ pub fn math_result_type(
|
||||
)
|
||||
}
|
||||
},
|
||||
Operator::Append => match (&lhs.ty, &rhs.ty) {
|
||||
(Type::List(a), Type::List(b)) => {
|
||||
if a == b {
|
||||
(Type::List(a.clone()), None)
|
||||
} else {
|
||||
(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)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
*op = Expression::garbage(op.span);
|
||||
(
|
||||
Type::Any,
|
||||
Some(ParseError::UnsupportedOperation(
|
||||
op.span,
|
||||
lhs.span,
|
||||
lhs.ty.clone(),
|
||||
rhs.span,
|
||||
rhs.ty.clone(),
|
||||
)),
|
||||
)
|
||||
}
|
||||
},
|
||||
Operator::Minus => match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Int, Type::Int) => (Type::Int, None),
|
||||
(Type::Float, Type::Int) => (Type::Float, None),
|
||||
|
@ -47,7 +47,8 @@ impl Expression {
|
||||
| Operator::Equal
|
||||
| Operator::NotEqual
|
||||
| Operator::In
|
||||
| Operator::NotIn => 80,
|
||||
| Operator::NotIn
|
||||
| Operator::Append => 80,
|
||||
Operator::BitAnd => 75,
|
||||
Operator::BitXor => 70,
|
||||
Operator::BitOr => 60,
|
||||
|
@ -14,6 +14,7 @@ pub enum Operator {
|
||||
RegexMatch,
|
||||
NotRegexMatch,
|
||||
Plus,
|
||||
Append,
|
||||
Minus,
|
||||
Multiply,
|
||||
Divide,
|
||||
@ -43,6 +44,7 @@ impl Display for Operator {
|
||||
Operator::RegexMatch => write!(f, "=~"),
|
||||
Operator::NotRegexMatch => write!(f, "!~"),
|
||||
Operator::Plus => write!(f, "+"),
|
||||
Operator::Append => write!(f, "++"),
|
||||
Operator::Minus => write!(f, "-"),
|
||||
Operator::Multiply => write!(f, "*"),
|
||||
Operator::Divide => write!(f, "/"),
|
||||
|
@ -1681,6 +1681,34 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append(&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 { vals: lhs, span })
|
||||
}
|
||||
(Value::List { vals: lhs, .. }, val) => {
|
||||
let mut lhs = lhs.clone();
|
||||
lhs.push(val.clone());
|
||||
Ok(Value::List { vals: lhs, span })
|
||||
}
|
||||
(val, Value::List { vals: rhs, .. }) => {
|
||||
let mut rhs = rhs.clone();
|
||||
rhs.insert(0, val.clone());
|
||||
Ok(Value::List { vals: rhs, span })
|
||||
}
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: self.get_type(),
|
||||
lhs_span: self.span()?,
|
||||
rhs_ty: rhs.get_type(),
|
||||
rhs_span: rhs.span()?,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
|
Loading…
Reference in New Issue
Block a user