Add not-in: operator (#1661)

This commit is contained in:
Jonathan Turner 2020-04-26 17:32:17 +12:00 committed by GitHub
parent ad8ab5b04d
commit ad7a3fd908
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 1 deletions

10
Cargo.lock generated
View file

@ -809,6 +809,15 @@ version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
[[package]]
name = "eml-parser"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9e30d14e24cd200f2351837a02feacf8f043410f2a56441868c93ef33f90239"
dependencies = [
"regex",
]
[[package]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "0.3.6" version = "0.3.6"
@ -2128,6 +2137,7 @@ dependencies = [
"derive-new", "derive-new",
"dirs 2.0.2", "dirs 2.0.2",
"dunce", "dunce",
"eml-parser",
"filesize", "filesize",
"futures 0.3.4", "futures 0.3.4",
"futures-util", "futures-util",

View file

@ -26,6 +26,7 @@ pub fn apply_operator(
Operator::Multiply => value::compute_values(op, left, right), Operator::Multiply => value::compute_values(op, left, right),
Operator::Divide => value::compute_values(op, left, right), Operator::Divide => value::compute_values(op, left, right),
Operator::In => table_contains(left, right).map(UntaggedValue::boolean), Operator::In => table_contains(left, right).map(UntaggedValue::boolean),
Operator::NotIn => table_contains(left, right).map(|x| UntaggedValue::boolean(!x)),
Operator::And => match (left.as_bool(), right.as_bool()) { Operator::And => match (left.as_bool(), right.as_bool()) {
(Ok(left), Ok(right)) => Ok(UntaggedValue::boolean(left && right)), (Ok(left), Ok(right)) => Ok(UntaggedValue::boolean(left && right)),
_ => Err((left.type_name(), right.type_name())), _ => Err((left.type_name(), right.type_name())),

View file

@ -20,6 +20,26 @@ fn filters_with_nothing_comparison() {
assert_eq!(actual, "7"); assert_eq!(actual, "7");
} }
#[test]
fn where_in_table() {
let actual = nu!(
cwd: "tests/fixtures/formats",
r#"echo '[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from-json | where name in: ["foo"] | get size | sum | echo $it"#
);
assert_eq!(actual, "5");
}
#[test]
fn where_not_in_table() {
let actual = nu!(
cwd: "tests/fixtures/formats",
r#"echo '[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from-json | where name not-in: ["foo"] | get size | sum | echo $it"#
);
assert_eq!(actual, "4");
}
#[test] #[test]
fn explicit_block_condition() { fn explicit_block_condition() {
let actual = nu!( let actual = nu!(

View file

@ -247,6 +247,8 @@ fn parse_operator(lite_arg: &Spanned<String>) -> (SpannedExpression, Option<Pars
Operator::Divide Operator::Divide
} else if lite_arg.item == "in:" { } else if lite_arg.item == "in:" {
Operator::In Operator::In
} else if lite_arg.item == "not-in:" {
Operator::NotIn
} else if lite_arg.item == "&&" { } else if lite_arg.item == "&&" {
Operator::And Operator::And
} else if lite_arg.item == "||" { } else if lite_arg.item == "||" {

View file

@ -450,7 +450,8 @@ impl SpannedExpression {
| Operator::GreaterThanOrEqual | Operator::GreaterThanOrEqual
| Operator::Equal | Operator::Equal
| Operator::NotEqual | Operator::NotEqual
| Operator::In => 80, | Operator::In
| Operator::NotIn => 80,
Operator::And => 50, Operator::And => 50,
Operator::Or => 40, // TODO: should we have And and Or be different precedence? Operator::Or => 40, // TODO: should we have And and Or be different precedence?
} }
@ -589,6 +590,7 @@ pub enum Operator {
Multiply, Multiply,
Divide, Divide,
In, In,
NotIn,
And, And,
Or, Or,
} }