From 106ca65c58a202713b990bc5844a3ee60b311bfd Mon Sep 17 00:00:00 2001 From: NitinL <37251096+initinll@users.noreply.github.com> Date: Thu, 16 Mar 2023 20:20:30 +0530 Subject: [PATCH] Added fix for bug #8278 to read tag values from YAML files (#8354) # Description This PR adds a fix for reading tag values from YAML file. A tag in YAML file is denoted by using the exclamation point ("!") symbol. For example - Key: !Value Additional passing test has also been added supporting the bug fix - - `test_convert_yaml_value_to_nu_value_for_tagged_values` The fix passes all the below required tests suites locally - >To check standard code formatting. - `cargo fmt --all -- --check` (`cargo fmt --all` applies these changes) >To check that you're using the standard code style. - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` >To check that all tests pass - `cargo test --workspace` --------- Co-authored-by: Nitin Londhe --- crates/nu-command/src/formats/from/yaml.rs | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/crates/nu-command/src/formats/from/yaml.rs b/crates/nu-command/src/formats/from/yaml.rs index 9400546049..ede932809c 100644 --- a/crates/nu-command/src/formats/from/yaml.rs +++ b/crates/nu-command/src/formats/from/yaml.rs @@ -174,6 +174,30 @@ fn convert_yaml_value_to_nu_value( Value::from(collected) } + serde_yaml::Value::Tagged(t) => { + let tag = &t.tag; + let value = match &t.value { + serde_yaml::Value::String(s) => { + let val = format!("{} {}", tag, s).trim().to_string(); + Value::String { val, span } + } + serde_yaml::Value::Number(n) => { + let val = format!("{} {}", tag, n).trim().to_string(); + Value::String { val, span } + } + serde_yaml::Value::Bool(b) => { + let val = format!("{} {}", tag, b).trim().to_string(); + Value::String { val, span } + } + serde_yaml::Value::Null => { + let val = format!("{}", tag).trim().to_string(); + Value::String { val, span } + } + v => convert_yaml_value_to_nu_value(v, span, val_span)?, + }; + + value + } serde_yaml::Value::Null => Value::nothing(span), x => unimplemented!("Unsupported YAML case: {:?}", x), }) @@ -314,4 +338,63 @@ mod test { test_examples(FromYaml {}) } + + #[test] + fn test_convert_yaml_value_to_nu_value_for_tagged_values() { + struct TestCase { + input: &'static str, + expected: Result, + } + + let test_cases: Vec = vec![ + TestCase { + input: "Key: !Value ${TEST}-Test-role", + expected: Ok(Value::Record { + cols: vec!["Key".to_string()], + vals: vec![Value::test_string("!Value ${TEST}-Test-role")], + span: Span::test_data(), + }), + }, + TestCase { + input: "Key: !Value test-${TEST}", + expected: Ok(Value::Record { + cols: vec!["Key".to_string()], + vals: vec![Value::test_string("!Value test-${TEST}")], + span: Span::test_data(), + }), + }, + TestCase { + input: "Key: !Value", + expected: Ok(Value::Record { + cols: vec!["Key".to_string()], + vals: vec![Value::test_string("!Value")], + span: Span::test_data(), + }), + }, + TestCase { + input: "Key: !True", + expected: Ok(Value::Record { + cols: vec!["Key".to_string()], + vals: vec![Value::test_string("!True")], + span: Span::test_data(), + }), + }, + TestCase { + input: "Key: !123", + expected: Ok(Value::Record { + cols: vec!["Key".to_string()], + vals: vec![Value::test_string("!123")], + span: Span::test_data(), + }), + }, + ]; + + for test_case in test_cases { + let doc = serde_yaml::Deserializer::from_str(test_case.input); + let v: serde_yaml::Value = serde_yaml::Value::deserialize(doc.last().unwrap()).unwrap(); + let result = convert_yaml_value_to_nu_value(&v, Span::test_data(), Span::test_data()); + assert!(result.is_ok()); + assert!(result.ok().unwrap() == test_case.expected.ok().unwrap()); + } + } }