Merge pull request #319 from jonathandturner/implement-whole-stream-command-for-all-commands

Implement whole stream command for all commands
This commit is contained in:
Jonathan Turner 2019-08-20 18:40:19 +12:00 committed by GitHub
commit 55f5893b59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 777 additions and 212 deletions

View File

@ -145,38 +145,37 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
use crate::commands::*; use crate::commands::*;
context.add_commands(vec![ context.add_commands(vec![
command("first", Box::new(first::first)), whole_stream_command(PS),
command("pick", Box::new(pick::pick)), whole_stream_command(LS),
command("from-array", Box::new(from_array::from_array)), whole_stream_command(CD),
command("from-ini", Box::new(from_ini::from_ini)), whole_stream_command(Size),
command("from-csv", Box::new(from_csv::from_csv)), whole_stream_command(Nth),
command("from-json", Box::new(from_json::from_json)), whole_stream_command(Next),
command("from-toml", Box::new(from_toml::from_toml)), whole_stream_command(Previous),
command("from-xml", Box::new(from_xml::from_xml)), whole_stream_command(Debug),
command("ps", Box::new(ps::ps)), whole_stream_command(Lines),
command("ls", Box::new(ls::ls)), whole_stream_command(Shells),
command("cd", Box::new(cd::cd)), whole_stream_command(SplitColumn),
command("size", Box::new(size::size)), whole_stream_command(SplitRow),
command("from-yaml", Box::new(from_yaml::from_yaml)), whole_stream_command(Lines),
command("nth", Box::new(nth::nth)), whole_stream_command(Reject),
command("n", Box::new(next::next)), whole_stream_command(Trim),
command("p", Box::new(prev::prev)), whole_stream_command(ToArray),
command("debug", Box::new(debug::debug)), whole_stream_command(ToCSV),
command("lines", Box::new(lines::lines)), whole_stream_command(ToJSON),
command("pick", Box::new(pick::pick)), whole_stream_command(ToTOML),
command("shells", Box::new(shells::shells)), whole_stream_command(ToYAML),
command("split-column", Box::new(split_column::split_column)), whole_stream_command(SortBy),
command("split-row", Box::new(split_row::split_row)), whole_stream_command(Tags),
command("lines", Box::new(lines::lines)), whole_stream_command(First),
command("reject", Box::new(reject::reject)), whole_stream_command(FromArray),
command("trim", Box::new(trim::trim)), whole_stream_command(FromCSV),
command("to-array", Box::new(to_array::to_array)), whole_stream_command(FromINI),
command("to-csv", Box::new(to_csv::to_csv)), whole_stream_command(FromJSON),
command("to-json", Box::new(to_json::to_json)), whole_stream_command(FromTOML),
command("to-toml", Box::new(to_toml::to_toml)), whole_stream_command(FromXML),
command("to-yaml", Box::new(to_yaml::to_yaml)), whole_stream_command(FromYAML),
command("sort-by", Box::new(sort_by::sort_by)), whole_stream_command(Pick),
command("tags", Box::new(tags::tags)),
whole_stream_command(Get), whole_stream_command(Get),
per_item_command(Remove), per_item_command(Remove),
per_item_command(Open), per_item_command(Open),

View File

@ -56,25 +56,54 @@ crate mod where_;
crate mod which_; crate mod which_;
crate use autoview::Autoview; crate use autoview::Autoview;
//crate use cd::Cd; crate use cd::CD;
crate use clip::Clip; crate use clip::Clip;
crate use command::{ crate use command::{
command, per_item_command, whole_stream_command, Command, CommandArgs, PerItemCommand, per_item_command, whole_stream_command, Command, CommandArgs, PerItemCommand, RawCommandArgs,
RawCommandArgs, UnevaluatedCallInfo, WholeStreamCommand, UnevaluatedCallInfo, WholeStreamCommand,
}; };
crate use config::Config; crate use config::Config;
crate use cp::Cpy; crate use cp::Cpy;
crate use date::Date; crate use date::Date;
crate use debug::Debug;
crate use enter::Enter; crate use enter::Enter;
crate use exit::Exit; crate use exit::Exit;
crate use first::First;
crate use from_array::FromArray;
crate use from_csv::FromCSV;
crate use from_ini::FromINI;
crate use from_json::FromJSON;
crate use from_toml::FromTOML;
crate use from_xml::FromXML;
crate use from_yaml::FromYAML;
crate use get::Get; crate use get::Get;
crate use lines::Lines;
crate use ls::LS;
crate use mkdir::Mkdir; crate use mkdir::Mkdir;
crate use mv::Move; crate use mv::Move;
crate use next::Next;
crate use nth::Nth;
crate use open::Open; crate use open::Open;
crate use pick::Pick;
crate use prev::Previous;
crate use ps::PS;
crate use reject::Reject;
crate use rm::Remove; crate use rm::Remove;
crate use save::Save; crate use save::Save;
crate use shells::Shells;
crate use size::Size;
crate use skip_while::SkipWhile; crate use skip_while::SkipWhile;
crate use sort_by::SortBy;
crate use split_column::SplitColumn;
crate use split_row::SplitRow;
crate use table::Table; crate use table::Table;
crate use tags::Tags;
crate use to_array::ToArray;
crate use to_csv::ToCSV;
crate use to_json::ToJSON;
crate use to_toml::ToTOML;
crate use to_yaml::ToYAML;
crate use trim::Trim;
crate use version::Version; crate use version::Version;
crate use vtable::VTable; crate use vtable::VTable;
crate use where_::Where; crate use where_::Where;

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
pub fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct CD;
impl WholeStreamCommand for CD {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
cd(args, registry)
}
fn name(&self) -> &str {
"cd"
}
fn signature(&self) -> Signature {
Signature::build("cd").optional("directory", SyntaxType::Path)
}
}
fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let shell_manager = args.shell_manager.clone(); let shell_manager = args.shell_manager.clone();
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
shell_manager.cd(args) shell_manager.cd(args)

View File

@ -635,43 +635,6 @@ impl WholeStreamCommand for FnFilterCommand {
} }
} }
pub struct FnRawCommand {
name: String,
func: Box<
dyn Fn(CommandArgs, &registry::CommandRegistry) -> Result<OutputStream, ShellError>
+ Send
+ Sync,
>,
}
impl WholeStreamCommand for FnRawCommand {
fn name(&self) -> &str {
&self.name
}
fn run(
&self,
args: CommandArgs,
registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError> {
(self.func)(args, registry)
}
}
pub fn command(
name: &str,
func: Box<
dyn Fn(CommandArgs, &registry::CommandRegistry) -> Result<OutputStream, ShellError>
+ Send
+ Sync,
>,
) -> Arc<Command> {
Arc::new(Command::WholeStream(Arc::new(FnRawCommand {
name: name.to_string(),
func,
})))
}
pub fn whole_stream_command(command: impl WholeStreamCommand + 'static) -> Arc<Command> { pub fn whole_stream_command(command: impl WholeStreamCommand + 'static) -> Arc<Command> {
Arc::new(Command::WholeStream(Arc::new(command))) Arc::new(Command::WholeStream(Arc::new(command)))
} }

View File

@ -1,6 +1,27 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
pub struct Debug;
impl WholeStreamCommand for Debug {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
debug(args, registry)
}
fn name(&self) -> &str {
"debug"
}
fn signature(&self) -> Signature {
Signature::build("debug")
}
}
pub fn debug(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn debug(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let input = args.input; let input = args.input;

View File

@ -1,18 +1,31 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::parser::CommandRegistry; use crate::parser::CommandRegistry;
use crate::prelude::*; use crate::prelude::*;
pub fn first(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct First;
let args = args.evaluate_once(registry)?;
if args.len() == 0 { impl WholeStreamCommand for First {
return Err(ShellError::labeled_error( fn run(
"First requires an amount", &self,
"needs parameter", args: CommandArgs,
args.name_span(), registry: &CommandRegistry,
)); ) -> Result<OutputStream, ShellError> {
first(args, registry)
} }
fn name(&self) -> &str {
"first"
}
fn signature(&self) -> Signature {
Signature::build("first").required("amount", SyntaxType::Literal)
}
}
fn first(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?;
let amount = args.expect_nth(0)?.as_i64(); let amount = args.expect_nth(0)?.as_i64();
let amount = match amount { let amount = match amount {

View File

@ -1,10 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::Value; use crate::object::Value;
use crate::prelude::*; use crate::prelude::*;
pub fn from_array( pub struct FromArray;
args: CommandArgs,
_registry: &CommandRegistry, impl WholeStreamCommand for FromArray {
) -> Result<OutputStream, ShellError> { fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_array(args, registry)
}
fn name(&self) -> &str {
"from-array"
}
fn signature(&self) -> Signature {
Signature::build("from-array")
}
}
fn from_array(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let stream = args let stream = args
.input .input
.values .values

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use csv::ReaderBuilder; use csv::ReaderBuilder;
pub struct FromCSV;
impl WholeStreamCommand for FromCSV {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_csv(args, registry)
}
fn name(&self) -> &str {
"from-csv"
}
fn signature(&self) -> Signature {
Signature::build("from-csv")
}
}
pub fn from_csv_string_to_value( pub fn from_csv_string_to_value(
s: String, s: String,
tag: impl Into<Tag>, tag: impl Into<Tag>,
@ -45,7 +66,7 @@ pub fn from_csv_string_to_value(
Ok(Tagged::from_item(Value::List(rows), tag)) Ok(Tagged::from_item(Value::List(rows), tag))
} }
pub fn from_csv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn from_csv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let span = args.name_span(); let span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
pub struct FromINI;
impl WholeStreamCommand for FromINI {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_ini(args, registry)
}
fn name(&self) -> &str {
"from-ini"
}
fn signature(&self) -> Signature {
Signature::build("from-ini")
}
}
fn convert_ini_second_to_nu_value( fn convert_ini_second_to_nu_value(
v: &HashMap<String, String>, v: &HashMap<String, String>,
tag: impl Into<Tag>, tag: impl Into<Tag>,
@ -37,7 +58,7 @@ pub fn from_ini_string_to_value(
Ok(convert_ini_top_to_nu_value(&v, tag)) Ok(convert_ini_top_to_nu_value(&v, tag))
} }
pub fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let span = args.name_span(); let span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::base::OF64; use crate::object::base::OF64;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct FromJSON;
impl WholeStreamCommand for FromJSON {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_json(args, registry)
}
fn name(&self) -> &str {
"from-json"
}
fn signature(&self) -> Signature {
Signature::build("from-json")
}
}
fn convert_json_value_to_nu_value(v: &serde_hjson::Value, tag: impl Into<Tag>) -> Tagged<Value> { fn convert_json_value_to_nu_value(v: &serde_hjson::Value, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into(); let tag = tag.into();
@ -43,10 +64,7 @@ pub fn from_json_string_to_value(
Ok(convert_json_value_to_nu_value(&v, tag)) Ok(convert_json_value_to_nu_value(&v, tag))
} }
pub fn from_json( fn from_json(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let span = args.name_span(); let span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::base::OF64; use crate::object::base::OF64;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct FromTOML;
impl WholeStreamCommand for FromTOML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_toml(args, registry)
}
fn name(&self) -> &str {
"from-toml"
}
fn signature(&self) -> Signature {
Signature::build("from-toml")
}
}
pub fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> Tagged<Value> { pub fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into(); let tag = tag.into();

View File

@ -1,6 +1,27 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct FromXML;
impl WholeStreamCommand for FromXML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_xml(args, registry)
}
fn name(&self) -> &str {
"from-xml"
}
fn signature(&self) -> Signature {
Signature::build("from-xml")
}
}
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Tagged<Value> { fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into(); let tag = tag.into();
@ -56,7 +77,7 @@ pub fn from_xml_string_to_value(
Ok(from_document_to_value(&parsed, tag)) Ok(from_document_to_value(&parsed, tag))
} }
pub fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let span = args.name_span(); let span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::base::OF64; use crate::object::base::OF64;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct FromYAML;
impl WholeStreamCommand for FromYAML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
from_yaml(args, registry)
}
fn name(&self) -> &str {
"from-yaml"
}
fn signature(&self) -> Signature {
Signature::build("from-yaml")
}
}
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into<Tag>) -> Tagged<Value> { fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into<Tag>) -> Tagged<Value> {
let tag = tag.into(); let tag = tag.into();
@ -47,10 +68,7 @@ pub fn from_yaml_string_to_value(
Ok(convert_yaml_value_to_nu_value(&v, tag)) Ok(convert_yaml_value_to_nu_value(&v, tag))
} }
pub fn from_yaml( fn from_yaml(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
args: CommandArgs,
_registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
let span = args.name_span(); let span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,11 +1,32 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::prelude::*; use crate::prelude::*;
use log::trace; use log::trace;
pub struct Lines;
impl WholeStreamCommand for Lines {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
lines(args, registry)
}
fn name(&self) -> &str {
"lines"
}
fn signature(&self) -> Signature {
Signature::build("lines")
}
}
// TODO: "Amount remaining" wrapper // TODO: "Amount remaining" wrapper
pub fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let span = args.name_span(); let span = args.name_span();
let input = args.input; let input = args.input;

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
pub fn ls(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct LS;
impl WholeStreamCommand for LS {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
ls(args, registry)
}
fn name(&self) -> &str {
"ls"
}
fn signature(&self) -> Signature {
Signature::build("ls").optional("path", SyntaxType::Path)
}
}
fn ls(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let shell_manager = args.shell_manager.clone(); let shell_manager = args.shell_manager.clone();
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
shell_manager.ls(args) shell_manager.ls(args)

View File

@ -1,7 +1,28 @@
use crate::commands::command::CommandAction; use crate::commands::command::CommandAction;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
pub fn next(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct Next;
impl WholeStreamCommand for Next {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
next(args, registry)
}
fn name(&self) -> &str {
"n"
}
fn signature(&self) -> Signature {
Signature::build("n")
}
}
fn next(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::NextShell))].into()) Ok(vec![Ok(ReturnSuccess::Action(CommandAction::NextShell))].into())
} }

View File

@ -1,32 +1,38 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::parser::CommandRegistry; use crate::parser::CommandRegistry;
use crate::prelude::*; use crate::prelude::*;
pub fn nth(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { #[derive(Deserialize)]
let args = args.evaluate_once(registry)?; struct NthArgs {
amount: Tagged<i64>,
}
if args.len() == 0 { pub struct Nth;
return Err(ShellError::labeled_error(
"Nth requires an amount", impl WholeStreamCommand for Nth {
"needs amount", fn run(
args.name_span(), &self,
)); args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, nth)?.run()
} }
let amount = args.expect_nth(0)?.as_i64(); fn name(&self) -> &str {
"nth"
}
let amount = match amount { fn signature(&self) -> Signature {
Ok(o) => o, Signature::build("nth").required("amount", SyntaxType::Any)
Err(_) => { }
return Err(ShellError::labeled_error( }
"Value is not a number",
"expected integer",
args.expect_nth(0)?.span(),
))
}
};
fn nth(
NthArgs { amount }: NthArgs,
RunnableContext { input, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
Ok(OutputStream::from_input( Ok(OutputStream::from_input(
args.input.values.skip(amount as u64).take(1), input.values.skip(amount.item as u64).take(1),
)) ))
} }

View File

@ -1,30 +1,47 @@
use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry; use crate::context::CommandRegistry;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::base::select_fields; use crate::object::base::select_fields;
use crate::prelude::*; use crate::prelude::*;
pub fn pick(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { #[derive(Deserialize)]
let args = args.evaluate_once(registry)?; struct PickArgs {
let len = args.len(); rest: Vec<Tagged<String>>,
let span = args.name_span(); }
let (input, args) = args.parts();
if len == 0 { pub struct Pick;
impl WholeStreamCommand for Pick {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, pick)?.run()
}
fn name(&self) -> &str {
"pick"
}
fn signature(&self) -> Signature {
Signature::build("pick").rest()
}
}
fn pick(
PickArgs { rest: fields }: PickArgs,
RunnableContext { input, name, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
if fields.len() == 0 {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Pick requires fields", "Pick requires fields",
"needs parameter", "needs parameter",
span, name,
)); ));
} }
let fields: Result<Vec<String>, _> = args let fields: Vec<_> = fields.iter().map(|f| f.item.clone()).collect();
.positional
.iter()
.flatten()
.map(|a| a.as_string())
.collect();
let fields = fields?;
let objects = input let objects = input
.values .values

View File

@ -2,6 +2,28 @@ use crate::commands::command::CommandAction;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
pub fn prev(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { use crate::commands::WholeStreamCommand;
pub struct Previous;
impl WholeStreamCommand for Previous {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
previous(args, registry)
}
fn name(&self) -> &str {
"p"
}
fn signature(&self) -> Signature {
Signature::build("p")
}
}
fn previous(_args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::PreviousShell))].into()) Ok(vec![Ok(ReturnSuccess::Action(CommandAction::PreviousShell))].into())
} }

View File

@ -1,9 +1,30 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::process::process_dict; use crate::object::process::process_dict;
use crate::prelude::*; use crate::prelude::*;
use sysinfo::{RefreshKind, SystemExt}; use sysinfo::{RefreshKind, SystemExt};
pub fn ps(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct PS;
impl WholeStreamCommand for PS {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
ps(args, registry)
}
fn name(&self) -> &str {
"ps"
}
fn signature(&self) -> Signature {
Signature::build("ps")
}
}
fn ps(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let mut system = sysinfo::System::new_with_specifics(RefreshKind::new().with_processes()); let mut system = sysinfo::System::new_with_specifics(RefreshKind::new().with_processes());
system.refresh_processes(); system.refresh_processes();
let list = system.get_process_list(); let list = system.get_process_list();

View File

@ -1,29 +1,46 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::base::reject_fields; use crate::object::base::reject_fields;
use crate::prelude::*; use crate::prelude::*;
pub fn reject(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { #[derive(Deserialize)]
let args = args.evaluate_once(registry)?; pub struct RejectArgs {
let len = args.len(); rest: Vec<Tagged<String>>,
let span = args.name_span(); }
let (input, args) = args.parts();
if len == 0 { pub struct Reject;
impl WholeStreamCommand for Reject {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, reject)?.run()
}
fn name(&self) -> &str {
"reject"
}
fn signature(&self) -> Signature {
Signature::build("reject").rest()
}
}
fn reject(
RejectArgs { rest: fields }: RejectArgs,
RunnableContext { input, name, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
if fields.len() == 0 {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Reject requires fields", "Reject requires fields",
"needs parameter", "needs parameter",
span, name,
)); ));
} }
let fields: Result<Vec<String>, _> = args let fields: Vec<_> = fields.iter().map(|f| f.item.clone()).collect();
.positional
.iter()
.flatten()
.map(|a| a.as_string())
.collect();
let fields = fields?;
let stream = input let stream = input
.values .values

View File

@ -1,8 +1,29 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::TaggedDictBuilder; use crate::object::TaggedDictBuilder;
use crate::prelude::*; use crate::prelude::*;
pub fn shells(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct Shells;
impl WholeStreamCommand for Shells {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
shells(args, registry)
}
fn name(&self) -> &str {
"shells"
}
fn signature(&self) -> Signature {
Signature::build("shells")
}
}
fn shells(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let mut shells_out = VecDeque::new(); let mut shells_out = VecDeque::new();
let span = args.call_info.name_span; let span = args.call_info.name_span;

View File

@ -1,8 +1,29 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{TaggedDictBuilder, Value}; use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct Size;
impl WholeStreamCommand for Size {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
size(args, registry)
}
fn name(&self) -> &str {
"size"
}
fn signature(&self) -> Signature {
Signature::build("size")
}
}
fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let input = args.input; let input = args.input;
let span = args.call_info.name_span; let span = args.call_info.name_span;
Ok(input Ok(input

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
pub fn sort_by(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct SortBy;
impl WholeStreamCommand for SortBy {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
sort_by(args, registry)
}
fn name(&self) -> &str {
"sort-by"
}
fn signature(&self) -> Signature {
Signature::build("sort-by")
}
}
fn sort_by(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let (input, args) = args.parts(); let (input, args) = args.parts();

View File

@ -1,38 +1,55 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use log::trace; use log::trace;
pub fn split_column( #[derive(Deserialize)]
args: CommandArgs, struct SplitColumnArgs {
registry: &CommandRegistry, separator: Tagged<String>,
) -> Result<OutputStream, ShellError> { rest: Vec<Tagged<String>>,
let args = args.evaluate_once(registry)?; }
let span = args.name_span();
let (input, args) = args.parts();
let positional: Vec<_> = args.positional.iter().flatten().cloned().collect(); pub struct SplitColumn;
if positional.len() == 0 { impl WholeStreamCommand for SplitColumn {
return Err(ShellError::labeled_error( fn run(
"Split-column needs more information", &self,
"needs parameter (eg split-column \",\")", args: CommandArgs,
span, registry: &CommandRegistry,
)); ) -> Result<OutputStream, ShellError> {
args.process(registry, split_column)?.run()
} }
fn name(&self) -> &str {
"split-column"
}
fn signature(&self) -> Signature {
Signature::build("split-column")
.required("separator", SyntaxType::Any)
.rest()
}
}
fn split_column(
SplitColumnArgs { separator, rest }: SplitColumnArgs,
RunnableContext { input, name, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
Ok(input Ok(input
.values .values
.map(move |v| match v.item { .map(move |v| match v.item {
Value::Primitive(Primitive::String(ref s)) => { Value::Primitive(Primitive::String(ref s)) => {
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n"); let splitter = separator.replace("\\n", "\n");
trace!("splitting with {:?}", splitter); trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
trace!("split result = {:?}", split_result); trace!("split result = {:?}", split_result);
let positional: Vec<_> = rest.iter().map(|f| f.item.clone()).collect();
// If they didn't provide column names, make up our own // If they didn't provide column names, make up our own
if (positional.len() - 1) == 0 { if positional.len() == 0 {
let mut gen_columns = vec![]; let mut gen_columns = vec![];
for i in 0..split_result.len() { for i in 0..split_result.len() {
gen_columns.push(format!("Column{}", i + 1)); gen_columns.push(format!("Column{}", i + 1));
@ -44,19 +61,16 @@ pub fn split_column(
} }
ReturnSuccess::value(dict.into_tagged_value()) ReturnSuccess::value(dict.into_tagged_value())
} else if split_result.len() == (positional.len() - 1) { } else if split_result.len() == positional.len() {
let mut dict = TaggedDictBuilder::new(v.tag()); let mut dict = TaggedDictBuilder::new(v.tag());
for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) { for (&k, v) in split_result.iter().zip(positional.iter()) {
dict.insert( dict.insert(v, Value::Primitive(Primitive::String(k.into())));
v.as_string().unwrap(),
Value::Primitive(Primitive::String(k.into())),
);
} }
ReturnSuccess::value(dict.into_tagged_value()) ReturnSuccess::value(dict.into_tagged_value())
} else { } else {
let mut dict = TaggedDictBuilder::new(v.tag()); let mut dict = TaggedDictBuilder::new(v.tag());
for k in positional.iter().skip(1) { for (&k, v) in split_result.iter().zip(positional.iter()) {
dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into())); dict.insert(v, Value::Primitive(Primitive::String(k.into())));
} }
ReturnSuccess::value(dict.into_tagged_value()) ReturnSuccess::value(dict.into_tagged_value())
} }
@ -64,7 +78,7 @@ pub fn split_column(
_ => Err(ShellError::labeled_error_with_secondary( _ => Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline", "Expected a string from pipeline",
"requires string input", "requires string input",
span, name,
"value originates from here", "value originates from here",
v.span(), v.span(),
)), )),

View File

@ -1,32 +1,43 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::prelude::*; use crate::prelude::*;
use log::trace; use log::trace;
pub fn split_row( #[derive(Deserialize)]
args: CommandArgs, struct SplitRowArgs {
registry: &CommandRegistry, separator: Tagged<String>,
) -> Result<OutputStream, ShellError> { }
let args = args.evaluate_once(registry)?;
let span = args.name_span();
let len = args.len();
let (input, args) = args.parts();
let positional: Vec<Tagged<Value>> = args.positional.iter().flatten().cloned().collect(); pub struct SplitRow;
if len == 0 { impl WholeStreamCommand for SplitRow {
return Err(ShellError::labeled_error( fn run(
"Split-row needs more information", &self,
"needs parameter (eg split-row \"\\n\")", args: CommandArgs,
span, registry: &CommandRegistry,
)); ) -> Result<OutputStream, ShellError> {
args.process(registry, split_row)?.run()
} }
fn name(&self) -> &str {
"split-row"
}
fn signature(&self) -> Signature {
Signature::build("split-row").required("separator", SyntaxType::Any)
}
}
fn split_row(
SplitRowArgs { separator }: SplitRowArgs,
RunnableContext { input, name, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
let stream = input let stream = input
.values .values
.map(move |v| match v.item { .map(move |v| match v.item {
Value::Primitive(Primitive::String(ref s)) => { Value::Primitive(Primitive::String(ref s)) => {
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n"); let splitter = separator.item.replace("\\n", "\n");
trace!("splitting with {:?}", splitter); trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect(); let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
@ -45,7 +56,7 @@ pub fn split_row(
result.push_back(Err(ShellError::labeled_error_with_secondary( result.push_back(Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline", "Expected a string from pipeline",
"requires string input", "requires string input",
span, name,
"value originates from here", "value originates from here",
v.span(), v.span(),
))); )));

View File

@ -1,8 +1,29 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{TaggedDictBuilder, Value}; use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub fn tags(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct Tags;
impl WholeStreamCommand for Tags {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
tags(args, registry)
}
fn name(&self) -> &str {
"tags"
}
fn signature(&self) -> Signature {
Signature::build("tags")
}
}
fn tags(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let source_map = args.call_info.source_map.clone(); let source_map = args.call_info.source_map.clone();
Ok(args Ok(args
.input .input

View File

@ -1,14 +1,34 @@
use crate::commands::WholeStreamCommand;
use crate::object::Value; use crate::object::Value;
use crate::prelude::*; use crate::prelude::*;
pub fn to_array( pub struct ToArray;
args: CommandArgs,
_registry: &CommandRegistry, impl WholeStreamCommand for ToArray {
) -> Result<OutputStream, ShellError> { fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_array(args, registry)
}
fn name(&self) -> &str {
"to-array"
}
fn signature(&self) -> Signature {
Signature::build("to-array")
}
}
fn to_array(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?;
let span = args.call_info.name_span;
let out = args.input.values.collect(); let out = args.input.values.collect();
Ok(out Ok(out
.map(|vec: Vec<_>| stream![Value::List(vec).tagged_unknown()]) // TODO: args.input should have a span .map(move |vec: Vec<_>| stream![Value::List(vec).simple_spanned(span)])
.flatten_stream() .flatten_stream()
.from_input_stream()) .from_input_stream())
} }

View File

@ -1,7 +1,28 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::prelude::*; use crate::prelude::*;
use csv::WriterBuilder; use csv::WriterBuilder;
pub struct ToCSV;
impl WholeStreamCommand for ToCSV {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_csv(args, registry)
}
fn name(&self) -> &str {
"to-csv"
}
fn signature(&self) -> Signature {
Signature::build("to-csv")
}
}
pub fn value_to_csv_value(v: &Value) -> Value { pub fn value_to_csv_value(v: &Value) -> Value {
match v { match v {
Value::Primitive(Primitive::String(s)) => Value::Primitive(Primitive::String(s.clone())), Value::Primitive(Primitive::String(s)) => Value::Primitive(Primitive::String(s.clone())),
@ -36,7 +57,7 @@ pub fn to_string(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
} }
} }
pub fn to_csv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn to_csv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let name_span = args.name_span(); let name_span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,6 +1,27 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct ToJSON;
impl WholeStreamCommand for ToJSON {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_json(args, registry)
}
fn name(&self) -> &str {
"to-json"
}
fn signature(&self) -> Signature {
Signature::build("to-json")
}
}
pub fn value_to_json_value(v: &Value) -> serde_json::Value { pub fn value_to_json_value(v: &Value) -> serde_json::Value {
match v { match v {
Value::Primitive(Primitive::Boolean(b)) => serde_json::Value::Bool(*b), Value::Primitive(Primitive::Boolean(b)) => serde_json::Value::Bool(*b),
@ -41,7 +62,7 @@ pub fn value_to_json_value(v: &Value) -> serde_json::Value {
} }
} }
pub fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let name_span = args.name_span(); let name_span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,6 +1,27 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct ToTOML;
impl WholeStreamCommand for ToTOML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_toml(args, registry)
}
fn name(&self) -> &str {
"to-toml"
}
fn signature(&self) -> Signature {
Signature::build("to-toml")
}
}
pub fn value_to_toml_value(v: &Value) -> toml::Value { pub fn value_to_toml_value(v: &Value) -> toml::Value {
match v { match v {
Value::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b), Value::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
@ -33,7 +54,7 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value {
} }
} }
pub fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let name_span = args.name_span(); let name_span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,6 +1,27 @@
use crate::commands::WholeStreamCommand;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::prelude::*; use crate::prelude::*;
pub struct ToYAML;
impl WholeStreamCommand for ToYAML {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
to_yaml(args, registry)
}
fn name(&self) -> &str {
"to-yaml"
}
fn signature(&self) -> Signature {
Signature::build("to-yaml")
}
}
pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value { pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {
match v { match v {
Value::Primitive(Primitive::Boolean(b)) => serde_yaml::Value::Bool(*b), Value::Primitive(Primitive::Boolean(b)) => serde_yaml::Value::Bool(*b),
@ -39,7 +60,7 @@ pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {
} }
} }
pub fn to_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { fn to_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; let args = args.evaluate_once(registry)?;
let name_span = args.name_span(); let name_span = args.name_span();
let out = args.input; let out = args.input;

View File

@ -1,8 +1,29 @@
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::Value; use crate::object::Value;
use crate::prelude::*; use crate::prelude::*;
pub fn trim(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct Trim;
impl WholeStreamCommand for Trim {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
trim(args, registry)
}
fn name(&self) -> &str {
"trim"
}
fn signature(&self) -> Signature {
Signature::build("trim")
}
}
fn trim(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let input = args.input; let input = args.input;
Ok(input Ok(input

View File

@ -186,13 +186,14 @@ impl ShellError {
ArgumentError::MissingMandatoryPositional(name) => Diagnostic::new( ArgumentError::MissingMandatoryPositional(name) => Diagnostic::new(
Severity::Error, Severity::Error,
format!( format!(
"{} requires {}", "{} requires {} parameter",
Color::Cyan.paint(command), Color::Cyan.paint(command),
Color::Green.bold().paint(name) Color::Green.bold().paint(name.clone())
), ),
) )
.with_label(Label::new_primary(span)), .with_label(
Label::new_primary(span).with_message(format!("requires {} parameter", name)),
),
ArgumentError::MissingValueForName(name) => Diagnostic::new( ArgumentError::MissingValueForName(name) => Diagnostic::new(
Severity::Error, Severity::Error,
format!( format!(