mirror of
https://github.com/nushell/nushell.git
synced 2024-12-23 15:39:06 +01:00
Handle not-in
operator
This commit is contained in:
parent
5f9ad0947d
commit
9e7e8ed48f
@ -191,6 +191,7 @@ pub fn eval_expression(
|
|||||||
Operator::Equal => lhs.eq(op_span, &rhs),
|
Operator::Equal => lhs.eq(op_span, &rhs),
|
||||||
Operator::NotEqual => lhs.ne(op_span, &rhs),
|
Operator::NotEqual => lhs.ne(op_span, &rhs),
|
||||||
Operator::In => lhs.r#in(op_span, &rhs),
|
Operator::In => lhs.r#in(op_span, &rhs),
|
||||||
|
Operator::NotIn => lhs.not_in(op_span, &rhs),
|
||||||
x => Err(ShellError::UnsupportedOperator(x, op_span)),
|
x => Err(ShellError::UnsupportedOperator(x, op_span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,6 +295,28 @@ pub fn math_result_type(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Operator::NotIn => match (&lhs.ty, &rhs.ty) {
|
||||||
|
(t, Type::List(u)) if type_compatible(t, u) => (Type::Bool, None),
|
||||||
|
(Type::Int | Type::Float, Type::Range) => (Type::Bool, None),
|
||||||
|
(Type::String, Type::String) => (Type::Bool, None),
|
||||||
|
(Type::String, Type::Record(_, _)) => (Type::Bool, None),
|
||||||
|
|
||||||
|
(Type::Unknown, _) => (Type::Bool, None),
|
||||||
|
(_, Type::Unknown) => (Type::Bool, None),
|
||||||
|
_ => {
|
||||||
|
*op = Expression::garbage(op.span);
|
||||||
|
(
|
||||||
|
Type::Unknown,
|
||||||
|
Some(ParseError::UnsupportedOperation(
|
||||||
|
op.span,
|
||||||
|
lhs.span,
|
||||||
|
lhs.ty.clone(),
|
||||||
|
rhs.span,
|
||||||
|
rhs.ty.clone(),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
*op = Expression::garbage(op.span);
|
*op = Expression::garbage(op.span);
|
||||||
|
@ -812,7 +812,7 @@ impl Value {
|
|||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
val: !matches!(ordering, Ordering::Less),
|
val: !matches!(ordering, Ordering::Equal),
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
@ -846,7 +846,7 @@ impl Value {
|
|||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
|
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
|
||||||
// TODO(@arthur-targaryen): Not sure about this clone.
|
// TODO(@arthur-targaryen): Not sure about this clone (see also `Value::not_in`).
|
||||||
val: rhs.clone().any(|x| lhs == &x),
|
val: rhs.clone().any(|x| lhs == &x),
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
@ -859,6 +859,41 @@ impl Value {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn not_in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
|
let span = span(&[self.span(), rhs.span()]);
|
||||||
|
|
||||||
|
match (self, rhs) {
|
||||||
|
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
val: !rhs.contains(lhs),
|
||||||
|
span,
|
||||||
|
}),
|
||||||
|
(Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
val: !rhs.contains(lhs),
|
||||||
|
span,
|
||||||
|
}),
|
||||||
|
(lhs, Value::List { vals: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
val: !rhs.contains(lhs),
|
||||||
|
span,
|
||||||
|
}),
|
||||||
|
(Value::String { val: lhs, .. }, Value::Record { cols: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
val: !rhs.contains(lhs),
|
||||||
|
span,
|
||||||
|
}),
|
||||||
|
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
// TODO(@arthur-targaryen): Not sure about this clone (see also `Value::r#in`).
|
||||||
|
val: rhs.clone().all(|x| lhs != &x),
|
||||||
|
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(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format a duration in nanoseconds into a string
|
/// Format a duration in nanoseconds into a string
|
||||||
|
10
src/tests.rs
10
src/tests.rs
@ -631,3 +631,13 @@ fn string_in_valuestream() -> TestResult {
|
|||||||
"true",
|
"true",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string_not_in_string() -> TestResult {
|
||||||
|
run_test(r#"'d' not-in 'abc'"#, "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn float_not_in_inc_range() -> TestResult {
|
||||||
|
run_test(r#"1.4 not-in 2..9.42"#, "true")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user