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

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)),
}
}
}