Merge pull request #183 from jonathandturner/fix_save

Fix up some of the save formats
This commit is contained in:
Jonathan Turner 2019-07-16 16:47:47 +12:00 committed by GitHub
commit b75e11b608
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 12 deletions

View file

@ -179,6 +179,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
command("to-array", Box::new(to_array::to_array)),
command("to-json", Box::new(to_json::to_json)),
command("to-toml", Box::new(to_toml::to_toml)),
command("to-yaml", Box::new(to_yaml::to_yaml)),
command("sort-by", Box::new(sort_by::sort_by)),
command("sort-by", Box::new(sort_by::sort_by)),
Arc::new(Open),

View file

@ -35,6 +35,7 @@ crate mod table;
crate mod to_array;
crate mod to_json;
crate mod to_toml;
crate mod to_yaml;
crate mod trim;
crate mod view;
crate mod vtable;

View file

@ -1,4 +1,7 @@
use crate::commands::command::SinkCommandArgs;
use crate::commands::to_json::value_to_json_value;
use crate::commands::to_toml::value_to_toml_value;
use crate::commands::to_yaml::value_to_yaml_value;
use crate::errors::ShellError;
use crate::object::{Primitive, Value};
use crate::parser::Spanned;
@ -48,15 +51,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
"saving to toml requires a single object (or use --raw)",
));
}
toml::to_string(&args.input[0]).unwrap()
}
Some(x) if x == "ini" && !save_raw => {
if args.input.len() != 1 {
return Err(ShellError::string(
"saving to ini requires a single object (or use --raw)",
));
}
serde_ini::to_string(&args.input[0]).unwrap()
toml::to_string(&value_to_toml_value(&args.input[0])).unwrap()
}
Some(x) if x == "json" && !save_raw => {
if args.input.len() != 1 {
@ -64,7 +59,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
"saving to json requires a single object (or use --raw)",
));
}
serde_json::to_string(&args.input[0]).unwrap()
serde_json::to_string(&value_to_json_value(&args.input[0])).unwrap()
}
Some(x) if x == "yml" && !save_raw => {
if args.input.len() != 1 {
@ -72,7 +67,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
"saving to yml requires a single object (or use --raw)",
));
}
serde_yaml::to_string(&args.input[0]).unwrap()
serde_yaml::to_string(&value_to_yaml_value(&args.input[0])).unwrap()
}
Some(x) if x == "yaml" && !save_raw => {
if args.input.len() != 1 {
@ -80,7 +75,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
"saving to yaml requires a single object (or use --raw)",
));
}
serde_yaml::to_string(&args.input[0]).unwrap()
serde_yaml::to_string(&value_to_yaml_value(&args.input[0])).unwrap()
}
_ => {
let mut save_data = String::new();

60
src/commands/to_yaml.rs Normal file
View file

@ -0,0 +1,60 @@
use crate::object::{Primitive, Value};
use crate::prelude::*;
pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {
match v {
Value::Primitive(Primitive::Boolean(b)) => serde_yaml::Value::Bool(*b),
Value::Primitive(Primitive::Bytes(b)) => {
serde_yaml::Value::Number(serde_yaml::Number::from(*b as u64))
}
Value::Primitive(Primitive::Date(d)) => serde_yaml::Value::String(d.to_string()),
Value::Primitive(Primitive::EndOfStream) => serde_yaml::Value::Null,
Value::Primitive(Primitive::Float(f)) => {
serde_yaml::Value::Number(serde_yaml::Number::from(f.into_inner()))
}
Value::Primitive(Primitive::Int(i)) => {
serde_yaml::Value::Number(serde_yaml::Number::from(*i))
}
Value::Primitive(Primitive::Nothing) => serde_yaml::Value::Null,
Value::Primitive(Primitive::String(s)) => serde_yaml::Value::String(s.clone()),
Value::Primitive(Primitive::Path(s)) => serde_yaml::Value::String(s.display().to_string()),
Value::Filesystem => serde_yaml::Value::Null,
Value::List(l) => {
serde_yaml::Value::Sequence(l.iter().map(|x| value_to_yaml_value(x)).collect())
}
Value::Block(_) => serde_yaml::Value::Null,
Value::Binary(b) => serde_yaml::Value::Sequence(
b.iter()
.map(|x| serde_yaml::Value::Number(serde_yaml::Number::from(*x)))
.collect(),
),
Value::Object(o) => {
let mut m = serde_yaml::Mapping::new();
for (k, v) in o.entries.iter() {
m.insert(serde_yaml::Value::String(k.clone()), value_to_yaml_value(v));
}
serde_yaml::Value::Mapping(m)
}
}
}
pub fn to_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let out = args.input;
let name_span = args.name_span;
Ok(out
.values
.map(
move |a| match serde_yaml::to_string(&value_to_yaml_value(&a)) {
Ok(x) => {
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span))
}
Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to YAML string",
"can not convert piped data to YAML string",
name_span,
)),
},
)
.to_output_stream())
}