mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 04:51:19 +02:00
Add xml open support
This commit is contained in:
@ -56,6 +56,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||
command("size", size::size),
|
||||
command("from-json", from_json::from_json),
|
||||
command("from-toml", from_toml::from_toml),
|
||||
command("from-xml", from_xml::from_xml),
|
||||
command("from-yaml", from_yaml::from_yaml),
|
||||
command("get", get::get),
|
||||
command("open", open::open),
|
||||
|
@ -8,6 +8,7 @@ crate mod config;
|
||||
crate mod first;
|
||||
crate mod from_json;
|
||||
crate mod from_toml;
|
||||
crate mod from_xml;
|
||||
crate mod from_yaml;
|
||||
crate mod get;
|
||||
crate mod ls;
|
||||
|
68
src/commands/from_xml.rs
Normal file
68
src/commands/from_xml.rs
Normal file
@ -0,0 +1,68 @@
|
||||
use crate::object::{DataDescriptor, Dictionary, Primitive, Value};
|
||||
use crate::prelude::*;
|
||||
|
||||
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>) -> Value {
|
||||
if n.is_element() {
|
||||
let name = n.tag_name().name().trim().to_string();
|
||||
|
||||
let mut children_values = vec![];
|
||||
for c in n.children() {
|
||||
children_values.push(from_node_to_value(&c));
|
||||
}
|
||||
|
||||
let children_values: Vec<Value> = children_values
|
||||
.into_iter()
|
||||
.filter(|x| match x {
|
||||
Value::Primitive(Primitive::String(f)) => {
|
||||
if f.trim() == "" {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
_ => true,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut collected = Dictionary::default();
|
||||
collected.add(
|
||||
DataDescriptor::from(name.clone()),
|
||||
Value::List(children_values),
|
||||
);
|
||||
|
||||
Value::Object(collected)
|
||||
} else if n.is_comment() {
|
||||
Value::Primitive(Primitive::String("<comment>".to_string()))
|
||||
} else if n.is_pi() {
|
||||
Value::Primitive(Primitive::String("<processing_instruction>".to_string()))
|
||||
} else if n.is_text() {
|
||||
Value::Primitive(Primitive::String(n.text().unwrap().to_string()))
|
||||
} else {
|
||||
Value::Primitive(Primitive::String("<unknown>".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
fn from_document_to_value(d: &roxmltree::Document) -> Value {
|
||||
from_node_to_value(&d.root_element())
|
||||
}
|
||||
|
||||
pub fn from_xml_string_to_value(s: String) -> Value {
|
||||
match roxmltree::Document::parse(&s) {
|
||||
Ok(doc) => from_document_to_value(&doc),
|
||||
Err(_) => Value::Error(Box::new(ShellError::string(
|
||||
"Can't convert string from xml".to_string(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
Ok(out
|
||||
.map(|a| match a {
|
||||
Value::Primitive(Primitive::String(s)) => ReturnValue::Value(from_xml_string_to_value(s)),
|
||||
_ => ReturnValue::Value(Value::Error(Box::new(ShellError::string(
|
||||
"Trying to convert XML from non-string".to_string(),
|
||||
)))),
|
||||
})
|
||||
.boxed())
|
||||
}
|
@ -32,6 +32,18 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
}
|
||||
}
|
||||
|
||||
let amount = args.positional[0].as_i64();
|
||||
|
||||
// If it's a number, get the row instead of the column
|
||||
if let Ok(amount) = amount {
|
||||
return Ok(args
|
||||
.input
|
||||
.skip(amount as u64)
|
||||
.take(1)
|
||||
.map(|v| ReturnValue::Value(v))
|
||||
.boxed());
|
||||
}
|
||||
|
||||
let fields: Result<Vec<String>, _> = args.positional.iter().map(|a| a.as_string()).collect();
|
||||
let fields = fields?;
|
||||
|
||||
|
@ -103,6 +103,11 @@ pub fn open(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
crate::commands::from_json::from_json_string_to_value(contents),
|
||||
));
|
||||
}
|
||||
Some(x) if x == "xml" && !open_raw => {
|
||||
stream.push_back(ReturnValue::Value(
|
||||
crate::commands::from_xml::from_xml_string_to_value(contents),
|
||||
));
|
||||
}
|
||||
Some(x) if x == "yml" && !open_raw => {
|
||||
stream.push_back(ReturnValue::Value(
|
||||
crate::commands::from_yaml::from_yaml_string_to_value(contents),
|
||||
|
@ -183,6 +183,18 @@ impl Value {
|
||||
crate fn get_data_by_key(&'a self, name: &str) -> Option<&Value> {
|
||||
match self {
|
||||
Value::Object(o) => o.get_data_by_key(name),
|
||||
Value::List(l) => {
|
||||
for item in l {
|
||||
match item {
|
||||
Value::Object(o) => match o.get_data_by_key(name) {
|
||||
Some(v) => return Some(v),
|
||||
None => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user