Added a first pass at sort-by

This commit is contained in:
Yehuda Katz 2019-05-17 08:55:50 -07:00
parent 9d8bb48d3f
commit 2feef6bd25
8 changed files with 94 additions and 5 deletions

10
Cargo.lock generated
View file

@ -388,6 +388,7 @@ dependencies = [
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustyline 4.0.0 (git+https://github.com/wycats/rustyline.git)",
"subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
@ -420,6 +421,14 @@ name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ordered-float"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parse-zoneinfo"
version = "0.2.0"
@ -811,6 +820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
"checksum parse-zoneinfo 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "089a398ccdcdd77b8c38909d5a1e4b67da1bc4c9dbfe6d5b536c828eddb779e5"
"checksum prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"

View file

@ -26,3 +26,4 @@ futures-core = "0.2.1"
indexmap = "1.0.2"
chrono-humanize = "0.0.11"
byte-unit = "2.1.0"
ordered-float = "1.0.2"

View file

@ -6,6 +6,7 @@ crate mod ps;
crate mod reject;
crate mod select;
crate mod skip;
crate mod sort_by;
crate mod take;
crate mod to_array;
crate mod where_;

29
src/commands/sort_by.rs Normal file
View file

@ -0,0 +1,29 @@
use crate::errors::ShellError;
use crate::prelude::*;
use derive_new::new;
#[derive(new)]
pub struct SortBy;
impl crate::Command for SortBy {
fn run(&self, args: CommandArgs<'caller>) -> Result<VecDeque<ReturnValue>, ShellError> {
let fields: Result<Vec<_>, _> = args.args.iter().map(|a| a.as_string()).collect();
let fields = fields?;
let mut output = args.input.into_iter().collect::<Vec<_>>();
output.sort_by_key(|item| {
fields
.iter()
.map(|f| item.get_data_by_key(f).borrow().copy())
.collect::<Vec<Value>>()
});
let output = output
.iter()
.map(|o| ReturnValue::Value(o.copy()))
.collect();
Ok(output)
}
}

View file

@ -4,7 +4,7 @@ use crate::prelude::*;
use crate::Value;
use derive_new::new;
#[derive(Debug, new)]
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, new)]
pub struct ShellError {
title: String,
error: Value,

View file

@ -74,6 +74,7 @@ fn main() -> Result<(), Box<Error>> {
("reject", Box::new(reject::Reject)),
("to-array", Box::new(to_array::ToArray)),
("where", Box::new(where_::Where)),
("sort-by", Box::new(sort_by::SortBy)),
]);
}

View file

@ -5,12 +5,12 @@ use chrono::{DateTime, Utc};
use chrono_humanize::Humanize;
use std::time::SystemTime;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum Primitive {
Nothing,
Int(i64),
#[allow(unused)]
Float(f64),
Float(ordered_float::OrderedFloat<f64>),
Bytes(u128),
String(String),
Boolean(bool),
@ -49,7 +49,7 @@ impl Primitive {
}
}
#[derive(Debug)]
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum Value {
Primitive(Primitive),
Object(crate::object::Dictionary),
@ -69,6 +69,15 @@ impl Value {
}
}
crate fn get_data_by_key(&'a self, name: &str) -> crate::MaybeOwned<'a, Value> {
match self {
Value::Primitive(_) => crate::MaybeOwned::Owned(Value::nothing()),
Value::Object(o) => o.get_data_by_key(name),
Value::List(_) => crate::MaybeOwned::Owned(Value::nothing()),
Value::Error(_) => crate::MaybeOwned::Owned(Value::nothing()),
}
}
crate fn get_data(&'a self, desc: &DataDescriptor) -> crate::MaybeOwned<'a, Value> {
match self {
Value::Primitive(_) => crate::MaybeOwned::Owned(Value::nothing()),

View file

@ -5,12 +5,43 @@ use crate::object::desc::DataDescriptor;
use crate::object::{Primitive, Value};
use crate::MaybeOwned;
use indexmap::IndexMap;
use std::cmp::{Ordering, PartialOrd};
#[derive(Debug, Default)]
#[derive(Debug, Default, Eq, PartialEq)]
pub struct Dictionary {
entries: IndexMap<String, Value>,
}
impl PartialOrd for Dictionary {
// TODO: FIXME
fn partial_cmp(&self, _other: &Dictionary) -> Option<Ordering> {
Some(Ordering::Less)
}
}
impl Ord for Dictionary {
// TODO: FIXME
fn cmp(&self, _other: &Dictionary) -> Ordering {
Ordering::Less
}
}
impl PartialOrd<Value> for Dictionary {
fn partial_cmp(&self, _other: &Value) -> Option<Ordering> {
Some(Ordering::Less)
}
}
impl PartialEq<Value> for Dictionary {
// TODO: FIXME
fn eq(&self, other: &Value) -> bool {
match other {
Value::Object(d) => self == d,
_ => false,
}
}
}
impl Dictionary {
crate fn add(&mut self, name: impl Into<String>, value: Value) {
self.entries.insert(name.into(), value);
@ -41,4 +72,11 @@ impl Dictionary {
None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)),
}
}
crate fn get_data_by_key(&self, name: &str) -> MaybeOwned<'_, Value> {
match self.entries.get(name) {
Some(v) => MaybeOwned::Borrowed(v),
None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)),
}
}
}