in/not-in for strings (#3906)

This commit is contained in:
JT 2021-08-07 09:49:37 +12:00 committed by GitHub
parent cd814851da
commit b6728efcd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 7 deletions

View file

@ -55,8 +55,8 @@ pub fn apply_operator(
)),
_ => res,
}),
Operator::In => table_contains(left, right).map(UntaggedValue::boolean),
Operator::NotIn => table_contains(left, right).map(|x| UntaggedValue::boolean(!x)),
Operator::In => inside_of(left, right).map(UntaggedValue::boolean),
Operator::NotIn => inside_of(left, right).map(|x| UntaggedValue::boolean(!x)),
Operator::And => match (left.as_bool(), right.as_bool()) {
(Ok(left), Ok(right)) => Ok(UntaggedValue::boolean(left && right)),
_ => Err((left.type_name(), right.type_name())),
@ -89,12 +89,12 @@ fn string_contains(
}
}
fn table_contains(
fn inside_of(
left: &UntaggedValue,
right: &UntaggedValue,
) -> Result<bool, (&'static str, &'static str)> {
match right {
UntaggedValue::Table(values) => {
match (left, right) {
(_, UntaggedValue::Table(values)) => {
Ok(values
.iter()
.any(|x| match compare_values(Operator::Equal, left, &x.value) {
@ -102,6 +102,10 @@ fn table_contains(
_ => false,
}))
}
(
UntaggedValue::Primitive(Primitive::String(lhs)),
UntaggedValue::Primitive(Primitive::String(rhs)),
) => Ok(rhs.contains(lhs)),
_ => Err((left.type_name(), right.type_name())),
}
}

View file

@ -130,7 +130,8 @@ mod tests {
#[test]
fn return_value_can_be_used_in_assert_eq() {
let v: ReturnValue = ReturnSuccess::value(UntaggedValue::nothing());
assert_eq!(v, v);
let v1: ReturnValue = ReturnSuccess::value(UntaggedValue::nothing());
let v2: ReturnValue = ReturnSuccess::value(UntaggedValue::nothing());
assert_eq!(v1, v2);
}
}

View file

@ -679,6 +679,31 @@ fn negative_decimal_start() {
assert_eq!(actual.out, "2.7");
}
#[test]
fn string_inside_of() {
let actual = nu!(
cwd: ".",
r#"
"bob" in "bobby"
"#
);
assert_eq!(actual.out, "true");
}
#[test]
fn string_not_inside_of() {
let actual = nu!(
cwd: ".",
r#"
"bob" not-in "bobby"
"#
);
assert_eq!(actual.out, "false");
}
#[test]
fn index_row() {
let actual = nu!(