forked from extern/nushell
Merge pull request #1 from jonathandturner/where_and_skip
Add support for skip and where
This commit is contained in:
commit
3c5117f84d
@ -5,7 +5,9 @@ crate mod ls;
|
|||||||
crate mod ps;
|
crate mod ps;
|
||||||
crate mod reject;
|
crate mod reject;
|
||||||
crate mod select;
|
crate mod select;
|
||||||
|
crate mod skip;
|
||||||
crate mod take;
|
crate mod take;
|
||||||
crate mod to_array;
|
crate mod to_array;
|
||||||
|
crate mod where_;
|
||||||
|
|
||||||
crate use to_array::to_array;
|
crate use to_array::to_array;
|
||||||
|
29
src/commands/skip.rs
Normal file
29
src/commands/skip.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use crate::errors::ShellError;
|
||||||
|
use crate::prelude::*;
|
||||||
|
use derive_new::new;
|
||||||
|
|
||||||
|
#[derive(new)]
|
||||||
|
pub struct Skip;
|
||||||
|
|
||||||
|
// TODO: "Amount remaining" wrapper
|
||||||
|
|
||||||
|
impl crate::Command for Skip {
|
||||||
|
fn run(&self, args: CommandArgs<'caller>) -> Result<VecDeque<ReturnValue>, ShellError> {
|
||||||
|
let amount = args.args[0].as_int()?;
|
||||||
|
|
||||||
|
let amount = if args.input.len() > amount as usize {
|
||||||
|
amount as usize
|
||||||
|
} else {
|
||||||
|
args.input.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
let out: VecDeque<ReturnValue> = args
|
||||||
|
.input
|
||||||
|
.into_iter()
|
||||||
|
.skip(amount)
|
||||||
|
.map(|v| ReturnValue::Value(v))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
}
|
30
src/commands/where_.rs
Normal file
30
src/commands/where_.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use crate::errors::ShellError;
|
||||||
|
use crate::object::base::find;
|
||||||
|
use crate::prelude::*;
|
||||||
|
use derive_new::new;
|
||||||
|
|
||||||
|
#[derive(new)]
|
||||||
|
pub struct Where;
|
||||||
|
|
||||||
|
impl crate::Command for Where {
|
||||||
|
fn run(&self, args: CommandArgs<'caller>) -> Result<VecDeque<ReturnValue>, ShellError> {
|
||||||
|
if args.args.is_empty() {
|
||||||
|
return Err(ShellError::string("select requires a field"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let field: Result<String, _> = args.args[0].as_string();
|
||||||
|
let field = field?;
|
||||||
|
|
||||||
|
let op: Result<String, _> = args.args[1].as_string();
|
||||||
|
let op = op?;
|
||||||
|
|
||||||
|
let objects = args
|
||||||
|
.input
|
||||||
|
.iter()
|
||||||
|
.filter(|item| find(&item, &field, &op, &args.args[2]))
|
||||||
|
.map(|item| ReturnValue::Value(item.copy()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(objects)
|
||||||
|
}
|
||||||
|
}
|
@ -59,10 +59,12 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
("ps", Box::new(ps::Ps)),
|
("ps", Box::new(ps::Ps)),
|
||||||
("ls", Box::new(ls::Ls)),
|
("ls", Box::new(ls::Ls)),
|
||||||
("cd", Box::new(cd::Cd)),
|
("cd", Box::new(cd::Cd)),
|
||||||
|
("skip", Box::new(skip::Skip)),
|
||||||
("take", Box::new(take::Take)),
|
("take", Box::new(take::Take)),
|
||||||
("select", Box::new(select::Select)),
|
("select", Box::new(select::Select)),
|
||||||
("reject", Box::new(reject::Reject)),
|
("reject", Box::new(reject::Reject)),
|
||||||
("to-array", Box::new(to_array::ToArray)),
|
("to-array", Box::new(to_array::ToArray)),
|
||||||
|
("where", Box::new(where_::Where))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +75,9 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
match readline {
|
match readline {
|
||||||
|
Ok(ref line) if line.trim() == "exit" => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
Ok(line) => {
|
Ok(line) => {
|
||||||
let result = crate::parser::shell_parser(&line)
|
let result = crate::parser::shell_parser(&line)
|
||||||
.map_err(|e| ShellError::string(format!("{:?}", e)))?;
|
.map_err(|e| ShellError::string(format!("{:?}", e)))?;
|
||||||
|
@ -120,6 +120,17 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate fn as_bool(&self) -> Result<bool, ShellError> {
|
||||||
|
match self {
|
||||||
|
Value::Primitive(Primitive::Boolean(b)) => Ok(*b),
|
||||||
|
// TODO: this should definitely be more general with better errors
|
||||||
|
other => Err(ShellError::string(format!(
|
||||||
|
"Expected integer, got {:?}",
|
||||||
|
other
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate fn string(s: impl Into<String>) -> Value {
|
crate fn string(s: impl Into<String>) -> Value {
|
||||||
Value::Primitive(Primitive::String(s.into()))
|
Value::Primitive(Primitive::String(s.into()))
|
||||||
}
|
}
|
||||||
@ -132,6 +143,10 @@ impl Value {
|
|||||||
Value::Primitive(Primitive::Int(s.into()))
|
Value::Primitive(Primitive::Int(s.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate fn bool(s: impl Into<bool>) -> Value {
|
||||||
|
Value::Primitive(Primitive::Boolean(s.into()))
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
crate fn system_date(s: SystemTime) -> Value {
|
crate fn system_date(s: SystemTime) -> Value {
|
||||||
Value::Primitive(Primitive::Date(s.into()))
|
Value::Primitive(Primitive::Date(s.into()))
|
||||||
@ -188,3 +203,86 @@ crate fn reject(obj: &Value, fields: &[String]) -> crate::object::Dictionary {
|
|||||||
|
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate fn find(obj: &Value, field: &str, op: &str, rhs: &Value) -> bool {
|
||||||
|
let descs = obj.data_descriptors();
|
||||||
|
match descs.iter().find(|d| d.name == *field) {
|
||||||
|
None => false,
|
||||||
|
Some(desc) => {
|
||||||
|
let v = obj.get_data(desc).borrow().copy();
|
||||||
|
//println!("'{:?}' '{}' '{:?}'", v, op, rhs);
|
||||||
|
|
||||||
|
match v {
|
||||||
|
Value::Primitive(Primitive::Boolean(b)) => {
|
||||||
|
match (op, rhs) {
|
||||||
|
("-eq", Value::Primitive(Primitive::Boolean(b2))) => {
|
||||||
|
b == *b2
|
||||||
|
}
|
||||||
|
("-ne", Value::Primitive(Primitive::Boolean(b2))) => {
|
||||||
|
b != *b2
|
||||||
|
}
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Primitive(Primitive::Bytes(i)) => {
|
||||||
|
match (op, rhs) {
|
||||||
|
("-lt", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i < (*i2 as u128)
|
||||||
|
}
|
||||||
|
("-gt", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i > (*i2 as u128)
|
||||||
|
}
|
||||||
|
("-le", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i <= (*i2 as u128)
|
||||||
|
}
|
||||||
|
("-ge", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i >= (*i2 as u128)
|
||||||
|
}
|
||||||
|
("-eq", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i == (*i2 as u128)
|
||||||
|
}
|
||||||
|
("-ne", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i != (*i2 as u128)
|
||||||
|
}
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Primitive(Primitive::Int(i)) => {
|
||||||
|
match (op, rhs) {
|
||||||
|
("-lt", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i < *i2
|
||||||
|
}
|
||||||
|
("-gt", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i > *i2
|
||||||
|
}
|
||||||
|
("-le", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i <= *i2
|
||||||
|
}
|
||||||
|
("-ge", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i >= *i2
|
||||||
|
}
|
||||||
|
("-eq", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i == *i2
|
||||||
|
}
|
||||||
|
("-ne", Value::Primitive(Primitive::Int(i2))) => {
|
||||||
|
i != *i2
|
||||||
|
}
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Primitive(Primitive::String(s)) => {
|
||||||
|
match (op, rhs) {
|
||||||
|
("-eq", Value::Primitive(Primitive::String(s2))) => {
|
||||||
|
s == *s2
|
||||||
|
}
|
||||||
|
("-ne", Value::Primitive(Primitive::String(s2))) => {
|
||||||
|
s != *s2
|
||||||
|
}
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@ pub enum Item {
|
|||||||
Quoted(String),
|
Quoted(String),
|
||||||
Bare(String),
|
Bare(String),
|
||||||
Int(i64),
|
Int(i64),
|
||||||
|
Boolean(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
@ -21,6 +22,7 @@ impl Item {
|
|||||||
Item::Quoted(s) => Value::Primitive(Primitive::String(s.clone())),
|
Item::Quoted(s) => Value::Primitive(Primitive::String(s.clone())),
|
||||||
Item::Bare(s) => Value::Primitive(Primitive::String(s.clone())),
|
Item::Bare(s) => Value::Primitive(Primitive::String(s.clone())),
|
||||||
Item::Int(i) => Value::Primitive(Primitive::Int(*i)),
|
Item::Int(i) => Value::Primitive(Primitive::Int(*i)),
|
||||||
|
Item::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,6 +32,7 @@ crate fn print_items(items: &[Item]) -> String {
|
|||||||
Item::Bare(s) => format!("{}", s),
|
Item::Bare(s) => format!("{}", s),
|
||||||
Item::Quoted(s) => format!("{:?}", s),
|
Item::Quoted(s) => format!("{:?}", s),
|
||||||
Item::Int(i) => format!("{:?}", i),
|
Item::Int(i) => format!("{:?}", i),
|
||||||
|
Item::Boolean(b) => format!("{:?}", b),
|
||||||
});
|
});
|
||||||
|
|
||||||
itertools::join(formatted, " ")
|
itertools::join(formatted, " ")
|
||||||
@ -40,7 +43,7 @@ impl Item {
|
|||||||
match self {
|
match self {
|
||||||
Item::Quoted(s) => s,
|
Item::Quoted(s) => s,
|
||||||
Item::Bare(s) => s,
|
Item::Bare(s) => s,
|
||||||
Item::Int(_) => unimplemented!(),
|
Item::Boolean(_) | Item::Int(_) => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,8 +65,13 @@ fn int(s: &str) -> IResult<&str, Item> {
|
|||||||
is_a("1234567890")(s).map(|(a, b)| (a, Item::Int(FromStr::from_str(b).unwrap())))
|
is_a("1234567890")(s).map(|(a, b)| (a, Item::Int(FromStr::from_str(b).unwrap())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn boolean(s: &str) -> IResult<&str, Item> {
|
||||||
|
alt((tag("true"), tag("false")))(s)
|
||||||
|
.map(|(a, b)| (a, Item::Boolean(FromStr::from_str(b).unwrap())))
|
||||||
|
}
|
||||||
|
|
||||||
fn command_token(s: &str) -> IResult<&str, Item> {
|
fn command_token(s: &str) -> IResult<&str, Item> {
|
||||||
alt((int, quoted, unquoted))(s)
|
alt((boolean, int, quoted, unquoted))(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_args(s: &str) -> IResult<&str, Vec<Item>> {
|
fn command_args(s: &str) -> IResult<&str, Vec<Item>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user