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 <nitin.londhe@genmills.com>
This commit is contained in:
NitinL 2023-03-16 20:20:30 +05:30 committed by GitHub
parent 4c97b3dd28
commit 106ca65c58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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<Value, ShellError>,
}
let test_cases: Vec<TestCase> = 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());
}
}
}