diff --git a/Cargo.lock b/Cargo.lock index 230d1dd2b0..a6feec745f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1623,6 +1623,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8b11d47987..18e2bf9d4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ dunce = "1.0.0" indexmap = { version = "1.0.2", features = ["serde-1"] } chrono-humanize = "0.0.11" byte-unit = "2.1.0" -ordered-float = "1.0.2" +ordered-float = {version = "1.0.2", features = ["serde"]} prettyprint = "0.7.0" futures-preview = { version = "0.3.0-alpha.16", features = ["compat", "io-compat"] } futures-sink-preview = "0.3.0-alpha.16" diff --git a/src/cli.rs b/src/cli.rs index 27bbf83443..92dce34e7b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -72,7 +72,6 @@ pub async fn cli() -> Result<(), Box> { command("reject", reject::reject), command("trim", trim::trim), command("to-array", to_array::to_array), - command("to-ini", to_ini::to_ini), command("to-json", to_json::to_json), command("to-toml", to_toml::to_toml), command("sort-by", sort_by::sort_by), diff --git a/src/commands.rs b/src/commands.rs index c5a9a4778c..db674c112b 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -31,7 +31,6 @@ crate mod split_row; crate mod sysinfo; crate mod table; crate mod to_array; -crate mod to_ini; crate mod to_json; crate mod to_toml; crate mod tree; diff --git a/src/commands/sysinfo.rs b/src/commands/sysinfo.rs index 7fb88901e1..2c1c4c88cb 100644 --- a/src/commands/sysinfo.rs +++ b/src/commands/sysinfo.rs @@ -62,31 +62,31 @@ pub fn sysinfo(_args: CommandArgs) -> Result { let mut mem_idx = indexmap::IndexMap::new(); mem_idx.insert( "total".to_string(), - Value::Primitive(Primitive::Bytes(x.total as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.total as u64 * 1024)), ); mem_idx.insert( "free".to_string(), - Value::Primitive(Primitive::Bytes(x.free as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.free as u64 * 1024)), ); mem_idx.insert( "avail".to_string(), - Value::Primitive(Primitive::Bytes(x.avail as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.avail as u64 * 1024)), ); mem_idx.insert( "buffers".to_string(), - Value::Primitive(Primitive::Bytes(x.buffers as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.buffers as u64 * 1024)), ); mem_idx.insert( "cached".to_string(), - Value::Primitive(Primitive::Bytes(x.cached as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.cached as u64 * 1024)), ); mem_idx.insert( "swap total".to_string(), - Value::Primitive(Primitive::Bytes(x.swap_total as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.swap_total as u64 * 1024)), ); mem_idx.insert( "swap free".to_string(), - Value::Primitive(Primitive::Bytes(x.swap_free as u128 * 1024)), + Value::Primitive(Primitive::Bytes(x.swap_free as u64 * 1024)), ); idx.insert("mem".to_string(), Value::Object(Dictionary::from(mem_idx))); @@ -151,10 +151,7 @@ pub fn sysinfo(_args: CommandArgs) -> Result { "temp".to_string(), Value::float(component.get_temperature() as f64), ); - component_idx.insert( - "max".to_string(), - Value::float(component.get_max() as f64), - ); + component_idx.insert("max".to_string(), Value::float(component.get_max() as f64)); if let Some(critical) = component.get_critical() { component_idx.insert("critical".to_string(), Value::float(critical as f64)); } @@ -177,10 +174,7 @@ pub fn sysinfo(_args: CommandArgs) -> Result { "available".to_string(), Value::bytes(disk.get_available_space()), ); - disk_idx.insert( - "total".to_string(), - Value::bytes(disk.get_total_space()), - ); + disk_idx.insert("total".to_string(), Value::bytes(disk.get_total_space())); v.push(Value::Object(Dictionary::from(disk_idx))); } @@ -194,7 +188,10 @@ pub fn sysinfo(_args: CommandArgs) -> Result { let mut network_idx = indexmap::IndexMap::new(); network_idx.insert("incoming".to_string(), Value::bytes(incoming)); network_idx.insert("outgoing".to_string(), Value::bytes(outgoing)); - idx.insert("network".to_string(), Value::Object(Dictionary::from(network_idx))); + idx.insert( + "network".to_string(), + Value::Object(Dictionary::from(network_idx)), + ); // println!("{:#?}", system.get_network()); diff --git a/src/commands/to_ini.rs b/src/commands/to_ini.rs deleted file mode 100644 index 4b23add216..0000000000 --- a/src/commands/to_ini.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::object::{Primitive, Value}; -use crate::prelude::*; - -pub fn to_ini(args: CommandArgs) -> Result { - let out = args.input; - let span = args.name_span; - Ok(out - .map(move |a| match serde_ini::to_string(&a) { - Ok(x) => ReturnValue::Value(Value::Primitive(Primitive::String(x))), - Err(_) => ReturnValue::Value(Value::Error(Box::new(ShellError::maybe_labeled_error( - "Can not convert to INI string", - "can not convert piped data to INI string", - span, - )))), - }) - .boxed()) -} diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index 6d245c6e18..51dee4fd6a 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -1,17 +1,54 @@ use crate::object::{Primitive, Value}; use crate::prelude::*; +pub fn value_to_json_value(v: &Value) -> serde_json::Value { + match v { + Value::Primitive(Primitive::Boolean(b)) => serde_json::Value::Bool(*b), + Value::Primitive(Primitive::Bytes(b)) => { + serde_json::Value::Number(serde_json::Number::from(*b as u64)) + } + Value::Primitive(Primitive::Date(d)) => serde_json::Value::String(d.to_string()), + Value::Primitive(Primitive::EndOfStream) => serde_json::Value::Null, + Value::Primitive(Primitive::Float(f)) => { + serde_json::Value::Number(serde_json::Number::from_f64(f.into_inner()).unwrap()) + } + Value::Primitive(Primitive::Int(i)) => { + serde_json::Value::Number(serde_json::Number::from(*i)) + } + Value::Primitive(Primitive::Nothing) => serde_json::Value::Null, + Value::Primitive(Primitive::String(s)) => serde_json::Value::String(s.clone()), + + Value::Filesystem => serde_json::Value::Null, + Value::List(l) => { + serde_json::Value::Array(l.iter().map(|x| value_to_json_value(x)).collect()) + } + Value::Error(e) => serde_json::Value::String(e.to_string()), + Value::Block(_) => serde_json::Value::Null, + Value::Object(o) => { + let mut m = serde_json::Map::new(); + for (k, v) in o.entries.iter() { + m.insert(k.name.display().to_string(), value_to_json_value(v)); + } + serde_json::Value::Object(m) + } + } +} + pub fn to_json(args: CommandArgs) -> Result { let out = args.input; let span = args.name_span; Ok(out - .map(move |a| match serde_json::to_string(&a) { - Ok(x) => ReturnValue::Value(Value::Primitive(Primitive::String(x))), - Err(_) => ReturnValue::Value(Value::Error(Box::new(ShellError::maybe_labeled_error( - "Can not convert to JSON string", - "can not convert piped data to JSON string", - span, - )))), - }) + .map( + move |a| match serde_json::to_string(&value_to_json_value(&a)) { + Ok(x) => ReturnValue::Value(Value::Primitive(Primitive::String(x))), + Err(_) => { + ReturnValue::Value(Value::Error(Box::new(ShellError::maybe_labeled_error( + "Can not convert to JSON string", + "can not convert piped data to JSON string", + span, + )))) + } + }, + ) .boxed()) } diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index 497276223c..4818ddd915 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -1,11 +1,38 @@ use crate::object::{Primitive, Value}; use crate::prelude::*; +pub fn value_to_toml_value(v: &Value) -> toml::Value { + match v { + Value::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b), + Value::Primitive(Primitive::Bytes(b)) => toml::Value::Integer(*b as i64), + Value::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()), + Value::Primitive(Primitive::EndOfStream) => { + toml::Value::String("".to_string()) + } + Value::Primitive(Primitive::Float(f)) => toml::Value::Float(f.into_inner()), + Value::Primitive(Primitive::Int(i)) => toml::Value::Integer(*i), + Value::Primitive(Primitive::Nothing) => toml::Value::String("".to_string()), + Value::Primitive(Primitive::String(s)) => toml::Value::String(s.clone()), + + Value::Filesystem => toml::Value::String("".to_string()), + Value::List(l) => toml::Value::Array(l.iter().map(|x| value_to_toml_value(x)).collect()), + Value::Error(e) => toml::Value::String(e.to_string()), + Value::Block(_) => toml::Value::String("".to_string()), + Value::Object(o) => { + let mut m = toml::map::Map::new(); + for (k, v) in o.entries.iter() { + m.insert(k.name.display().to_string(), value_to_toml_value(v)); + } + toml::Value::Table(m) + } + } +} + pub fn to_toml(args: CommandArgs) -> Result { let out = args.input; let span = args.name_span; Ok(out - .map(move |a| match toml::to_string(&a) { + .map(move |a| match toml::to_string(&value_to_toml_value(&a)) { Ok(x) => ReturnValue::Value(Value::Primitive(Primitive::String(x))), Err(_) => ReturnValue::Value(Value::Error(Box::new(ShellError::maybe_labeled_error( "Can not convert to TOML string", diff --git a/src/object/base.rs b/src/object/base.rs index acfc815067..337b223e90 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -13,7 +13,7 @@ use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer} use std::fmt; use std::time::SystemTime; -#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, new)] +#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, new, Serialize, Deserialize)] pub struct OF64 { crate inner: OrderedFloat, } @@ -30,13 +30,13 @@ impl From for OF64 { } } -#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deserialize)] +#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)] pub enum Primitive { Nothing, Int(i64), #[allow(unused)] Float(OF64), - Bytes(u128), + Bytes(u64), String(String), Boolean(bool), Date(DateTime), @@ -44,6 +44,7 @@ pub enum Primitive { EndOfStream, } +/* impl Serialize for Primitive { fn serialize(&self, serializer: S) -> Result where @@ -61,6 +62,7 @@ impl Serialize for Primitive { } } } +*/ impl Primitive { crate fn type_name(&self) -> String { @@ -99,7 +101,7 @@ impl Primitive { Primitive::Nothing => format!("{}", Color::Black.bold().paint("-")), Primitive::EndOfStream => format!("{}", Color::Black.bold().paint("-")), Primitive::Bytes(b) => { - let byte = byte_unit::Byte::from_bytes(*b); + let byte = byte_unit::Byte::from_bytes(*b as u128); if byte.get_bytes() == 0u128 { return Color::Black.bold().paint("Empty".to_string()).to_string(); @@ -194,7 +196,7 @@ impl Block { } } -#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)] +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Serialize, Deserialize)] pub enum Value { Primitive(Primitive), Object(crate::object::Dictionary), @@ -404,7 +406,7 @@ impl Value { crate fn as_i64(&self) -> Result { match self { Value::Primitive(Primitive::Int(i)) => Ok(*i), - Value::Primitive(Primitive::Bytes(b)) if *b <= std::i64::MAX as u128 => Ok(*b as i64), + Value::Primitive(Primitive::Bytes(b)) => Ok(*b as i64), // TODO: this should definitely be more general with better errors other => Err(ShellError::string(format!( "Expected integer, got {:?}", @@ -435,7 +437,7 @@ impl Value { Value::Primitive(Primitive::String(s.into())) } - pub fn bytes(s: impl Into) -> Value { + pub fn bytes(s: impl Into) -> Value { Value::Primitive(Primitive::Bytes(s.into())) } @@ -529,20 +531,18 @@ crate fn find(obj: &Value, field: &str, op: &Operator, rhs: &Value) -> bool { _ => false, }, Value::Primitive(Primitive::Bytes(i)) => match (op, rhs) { - (Operator::LessThan, Value::Primitive(Primitive::Int(i2))) => i < (*i2 as u128), + (Operator::LessThan, Value::Primitive(Primitive::Int(i2))) => i < (*i2 as u64), (Operator::GreaterThan, Value::Primitive(Primitive::Int(i2))) => { - i > (*i2 as u128) + i > (*i2 as u64) } (Operator::LessThanOrEqual, Value::Primitive(Primitive::Int(i2))) => { - i <= (*i2 as u128) + i <= (*i2 as u64) } (Operator::GreaterThanOrEqual, Value::Primitive(Primitive::Int(i2))) => { - i >= (*i2 as u128) - } - (Operator::Equal, Value::Primitive(Primitive::Int(i2))) => i == (*i2 as u128), - (Operator::NotEqual, Value::Primitive(Primitive::Int(i2))) => { - i != (*i2 as u128) + i >= (*i2 as u64) } + (Operator::Equal, Value::Primitive(Primitive::Int(i2))) => i == (*i2 as u64), + (Operator::NotEqual, Value::Primitive(Primitive::Int(i2))) => i != (*i2 as u64), _ => false, }, Value::Primitive(Primitive::Int(i)) => match (op, rhs) { diff --git a/src/object/files.rs b/src/object/files.rs index b42a7ce3bb..a169b3d1dd 100644 --- a/src/object/files.rs +++ b/src/object/files.rs @@ -29,7 +29,7 @@ crate fn dir_entry_dict(entry: &std::fs::DirEntry) -> Result dict.add("created", Value::system_date(c)), diff --git a/src/object/serialization.rs b/src/object/serialization.rs index 85e7743a97..8addd565f8 100644 --- a/src/object/serialization.rs +++ b/src/object/serialization.rs @@ -24,6 +24,7 @@ impl Visitor<'_> for OF64Visitor { } } +/* impl<'de> Deserialize<'de> for OF64 { fn deserialize(deserializer: D) -> Result where @@ -32,7 +33,9 @@ impl<'de> Deserialize<'de> for OF64 { deserializer.deserialize_f64(OF64Visitor) } } +*/ +/* impl Serialize for Value { fn serialize(&self, serializer: S) -> Result where @@ -48,7 +51,7 @@ impl Serialize for Value { } } } - +*/ struct ValueVisitor; impl<'de> Visitor<'de> for ValueVisitor { @@ -102,6 +105,7 @@ impl<'de> Visitor<'de> for ValueVisitor { } } +/* impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result where @@ -110,3 +114,4 @@ impl<'de> Deserialize<'de> for Value { deserializer.deserialize_any(ValueVisitor) } } +*/ diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index 98d1b95f34..d6ac3d84bf 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -68,28 +68,31 @@ fn main() -> Result<(), Box> { } Value::Primitive(Primitive::Bytes(b)) => { send_response(vec![ReturnValue::Value(Value::bytes( - b + inc_by as u128, + b + inc_by as u64, ))]); } - _ => { + x => { send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Unrecognized type in stream"), + ShellError::string(format!("Unrecognized type in stream: {:?}", x)), )))]); } }, Ok(NuCommand::quit) => { break; } - Err(_) => { + Err(e) => { send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Unrecognized type in stream"), + ShellError::string(format!( + "Unrecognized type in stream: {} {:?}", + input, e + )), )))]); } } } Err(_) => { send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Unrecognized type in stream"), + ShellError::string(format!("Unrecognized type in stream: {}", input)), )))]); } } diff --git a/src/plugins/sum.rs b/src/plugins/sum.rs index 431452dc21..0bbfc6a5ff 100644 --- a/src/plugins/sum.rs +++ b/src/plugins/sum.rs @@ -53,7 +53,7 @@ fn main() -> Result<(), Box> { } Value::Primitive(Primitive::Bytes(b)) => { total += b as i64; - send_response(vec![ReturnValue::Value(Value::bytes(total as u128))]); + send_response(vec![ReturnValue::Value(Value::bytes(total as u64))]); } _ => { send_response(vec![ReturnValue::Value(Value::Error(Box::new(