Added attributes to from-xml command (#1272)

* Added attributes to from-xml command

* Added attributes as their own rows

* Removed unneccesary lifetime declarations

* from-xml now has children and attributes side by side

* Fixed tests and linting

* Fixed lint-problem
This commit is contained in:
Borimino 2020-01-25 17:16:40 +01:00 committed by Jonathan Turner
parent 83db5c34c3
commit 583f27dc41
2 changed files with 126 additions and 10 deletions

View File

@ -27,6 +27,17 @@ impl WholeStreamCommand for FromXML {
} }
} }
fn from_attributes_to_value(attributes: &[roxmltree::Attribute], tag: impl Into<Tag>) -> Value {
let tag = tag.into();
let mut collected = TaggedDictBuilder::new(tag);
for a in attributes {
collected.insert_untagged(String::from(a.name()), UntaggedValue::string(a.value()));
}
collected.into_value()
}
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Value { fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Value {
let tag = tag.into(); let tag = tag.into();
@ -51,8 +62,17 @@ fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>)
}) })
.collect(); .collect();
let mut collected = TaggedDictBuilder::new(tag); let mut collected = TaggedDictBuilder::new(&tag);
collected.insert_untagged(name, UntaggedValue::Table(children_values));
let attribute_value: Value = from_attributes_to_value(&n.attributes(), &tag);
let mut row = TaggedDictBuilder::new(&tag);
row.insert_untagged(
String::from("children"),
UntaggedValue::Table(children_values),
);
row.insert_untagged(String::from("attributes"), attribute_value);
collected.insert_untagged(name, row.into_value());
collected.into_value() collected.into_value()
} else if n.is_comment() { } else if n.is_comment() {
@ -163,7 +183,10 @@ mod tests {
assert_eq!( assert_eq!(
parse(source)?, parse(source)?,
row(indexmap! { row(indexmap! {
"nu".into() => table(&[]) "nu".into() => row(indexmap! {
"children".into() => table(&[]),
"attributes".into() => row(indexmap! {})
})
}) })
); );
@ -177,7 +200,10 @@ mod tests {
assert_eq!( assert_eq!(
parse(source)?, parse(source)?,
row(indexmap! { row(indexmap! {
"nu".into() => table(&[string("La era de los tres caballeros")]) "nu".into() => row(indexmap! {
"children".into() => table(&[string("La era de los tres caballeros")]),
"attributes".into() => row(indexmap! {})
})
}) })
); );
@ -196,11 +222,101 @@ mod tests {
assert_eq!( assert_eq!(
parse(source)?, parse(source)?,
row(indexmap! { row(indexmap! {
"nu".into() => table(&[ "nu".into() => row(indexmap! {
row(indexmap! {"dev".into() => table(&[string("Andrés")])}), "children".into() => table(&[
row(indexmap! {"dev".into() => table(&[string("Jonathan")])}), row(indexmap! {
row(indexmap! {"dev".into() => table(&[string("Yehuda")])}) "dev".into() => row(indexmap! {
]) "children".into() => table(&[string("Andrés")]),
"attributes".into() => row(indexmap! {})
})
}),
row(indexmap! {
"dev".into() => row(indexmap! {
"children".into() => table(&[string("Jonathan")]),
"attributes".into() => row(indexmap! {})
})
}),
row(indexmap! {
"dev".into() => row(indexmap! {
"children".into() => table(&[string("Yehuda")]),
"attributes".into() => row(indexmap! {})
})
})
]),
"attributes".into() => row(indexmap! {})
})
})
);
Ok(())
}
#[test]
fn parses_element_with_attribute() -> Result<(), roxmltree::Error> {
let source = "\
<nu version=\"2.0\">
</nu>";
assert_eq!(
parse(source)?,
row(indexmap! {
"nu".into() => row(indexmap! {
"children".into() => table(&[]),
"attributes".into() => row(indexmap! {
"version".into() => string("2.0")
})
})
})
);
Ok(())
}
#[test]
fn parses_element_with_attribute_and_element() -> Result<(), roxmltree::Error> {
let source = "\
<nu version=\"2.0\">
<version>2.0</version>
</nu>";
assert_eq!(
parse(source)?,
row(indexmap! {
"nu".into() => row(indexmap! {
"children".into() => table(&[
row(indexmap! {
"version".into() => row(indexmap! {
"children".into() => table(&[string("2.0")]),
"attributes".into() => row(indexmap! {})
})
})
]),
"attributes".into() => row(indexmap! {
"version".into() => string("2.0")
})
})
})
);
Ok(())
}
#[test]
fn parses_element_with_multiple_attributes() -> Result<(), roxmltree::Error> {
let source = "\
<nu version=\"2.0\" age=\"25\">
</nu>";
assert_eq!(
parse(source)?,
row(indexmap! {
"nu".into() => row(indexmap! {
"children".into() => table(&[]),
"attributes".into() => row(indexmap! {
"version".into() => string("2.0"),
"age".into() => string("25")
})
})
}) })
); );

View File

@ -189,7 +189,7 @@ fn parses_json() {
fn parses_xml() { fn parses_xml() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
"open jonathan.xml | get rss.channel | get item | get link | echo $it" "open jonathan.xml | get rss.children.channel.children | get item.children | get link.children | echo $it"
); );
assert_eq!( assert_eq!(