forked from extern/nushell
Add support for mult-doc YAML files (#3870)
Single doc YAML files are returned as before. Multi-doc YAML files are wrapped in an outer Table. Empty YAML files return Nothing.
This commit is contained in:
parent
69083bfca0
commit
370ae8c20c
@ -121,14 +121,26 @@ fn convert_yaml_value_to_nu_value(
|
|||||||
|
|
||||||
pub fn from_yaml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
pub fn from_yaml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
let v: serde_yaml::Value = serde_yaml::from_str(&s).map_err(|x| {
|
|
||||||
ShellError::labeled_error(
|
let mut documents = vec![];
|
||||||
format!("Could not load yaml: {}", x),
|
|
||||||
"could not load yaml from text",
|
for document in serde_yaml::Deserializer::from_str(&s) {
|
||||||
&tag,
|
let v: serde_yaml::Value = serde_yaml::Value::deserialize(document).map_err(|x| {
|
||||||
)
|
ShellError::labeled_error(
|
||||||
})?;
|
format!("Could not load yaml: {}", x),
|
||||||
convert_yaml_value_to_nu_value(&v, tag)
|
"could not load yaml from text",
|
||||||
|
&tag,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
documents.push(convert_yaml_value_to_nu_value(&v, tag.clone())?);
|
||||||
|
}
|
||||||
|
|
||||||
|
match documents.len() {
|
||||||
|
0 => Ok(UntaggedValue::nothing().into_value(tag)),
|
||||||
|
1 => Ok(documents.remove(0)),
|
||||||
|
_ => Ok(UntaggedValue::Table(documents).into_value(tag)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
@ -160,6 +172,8 @@ mod tests {
|
|||||||
use super::ShellError;
|
use super::ShellError;
|
||||||
use super::*;
|
use super::*;
|
||||||
use nu_protocol::row;
|
use nu_protocol::row;
|
||||||
|
use nu_test_support::value::int;
|
||||||
|
use nu_test_support::value::row;
|
||||||
use nu_test_support::value::string;
|
use nu_test_support::value::string;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -202,4 +216,43 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_empty_yaml() {
|
||||||
|
let input = "";
|
||||||
|
|
||||||
|
let expected = UntaggedValue::nothing().into_value(Tag::default());
|
||||||
|
|
||||||
|
let actual = from_yaml_string_to_value(input.to_owned(), Tag::default());
|
||||||
|
|
||||||
|
assert_eq!(Ok(expected), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_single_doc_yaml() {
|
||||||
|
let input = "k: 107\nj: '106'\n";
|
||||||
|
|
||||||
|
let expected =
|
||||||
|
UntaggedValue::row(indexmap! {"k".into() => int(107), "j".into() => string("106") })
|
||||||
|
.into_value(Tag::default());
|
||||||
|
|
||||||
|
let actual = from_yaml_string_to_value(input.to_owned(), Tag::default());
|
||||||
|
|
||||||
|
assert_eq!(Ok(expected), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multidoc_yaml() {
|
||||||
|
let input = "---\nk: 107\n---\nj: '106'\n";
|
||||||
|
|
||||||
|
let expected = UntaggedValue::table(&[
|
||||||
|
row(indexmap! {"k".into() => int(107) }),
|
||||||
|
row(indexmap! {"j".into() => string("106") }),
|
||||||
|
])
|
||||||
|
.into_value(Tag::default());
|
||||||
|
|
||||||
|
let actual = from_yaml_string_to_value(input.to_owned(), Tag::default());
|
||||||
|
|
||||||
|
assert_eq!(Ok(expected), actual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user