From 7f06d6144f050595b40e84ef193379785b22c5a8 Mon Sep 17 00:00:00 2001 From: Arthur Targaryen Date: Sat, 9 Oct 2021 11:23:32 +0200 Subject: [PATCH] Support `in` operator for record and value stream --- crates/nu-parser/src/type_check.rs | 1 + crates/nu-protocol/src/value/mod.rs | 22 +++++++++++++++++++--- src/tests.rs | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/crates/nu-parser/src/type_check.rs b/crates/nu-parser/src/type_check.rs index f41e6787d..d2f972cab 100644 --- a/crates/nu-parser/src/type_check.rs +++ b/crates/nu-parser/src/type_check.rs @@ -277,6 +277,7 @@ pub fn math_result_type( (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), diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 01aa379ab..9ccb623da 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -1066,9 +1066,25 @@ impl Value { span, }), (lhs, Value::List { vals: rhs, .. }) => Ok(Value::Bool { - val: rhs - .iter() - .any(|x| lhs.eq(Span::unknown(), x).map_or(false, |v| v.is_true())), + val: rhs.iter().any(|x| { + matches!( + lhs.eq(Span::unknown(), x), + Ok(Value::Bool { val: true, .. }) + ) + }), + 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 { + val: rhs.clone().any(|x| { + matches!( + lhs.eq(Span::unknown(), &x), + Ok(Value::Bool { val: true, .. }) + ) + }), span, }), _ => Err(ShellError::OperatorMismatch { diff --git a/src/tests.rs b/src/tests.rs index 9acb6913d..2de6466fb 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -608,3 +608,26 @@ fn int_in_exclusive_range() -> TestResult { fn non_number_in_range() -> TestResult { fail_test(r#"'a' in 1..3"#, "mismatched for operation") } + +#[test] +fn string_in_record() -> TestResult { + run_test(r#""a" in ('{ "a": 13, "b": 14 }' | from json)"#, "true") +} + +#[test] +fn non_string_in_record() -> TestResult { + fail_test( + r#"4 in ('{ "a": 13, "b": 14 }' | from json)"#, + "mismatch during operation", + ) +} + +#[test] +fn string_in_valuestream() -> TestResult { + run_test( + r#" + 'Hello' in ("Hello + World" | lines)"#, + "true", + ) +}