Switch to "engine-p" (#3270)

* WIP

* WIP

* first builds

* Tests pass
This commit is contained in:
Jonathan Turner 2021-04-07 04:19:43 +12:00 committed by GitHub
parent ad1c4f5e39
commit 073e5727c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
262 changed files with 2269 additions and 2660 deletions

4
Cargo.lock generated
View File

@ -3241,8 +3241,6 @@ version = "0.29.1"
dependencies = [
"Inflector",
"arboard",
"async-recursion",
"async-trait",
"base64 0.13.0",
"bigdecimal",
"byte-unit",
@ -3265,8 +3263,6 @@ dependencies = [
"filesize",
"fs_extra",
"futures 0.3.13",
"futures-util",
"futures_codec",
"getset",
"glob",
"hamcrest2",

View File

@ -123,13 +123,13 @@ pub fn search_paths() -> Vec<std::path::PathBuf> {
search_paths
}
pub async fn run_script_file(options: Options) -> Result<(), Box<dyn Error>> {
pub fn run_script_file(options: Options) -> Result<(), Box<dyn Error>> {
let context = create_default_context(false)?;
if let Some(cfg) = options.config {
load_cfg_as_global_cfg(&context, PathBuf::from(cfg)).await;
load_cfg_as_global_cfg(&context, PathBuf::from(cfg));
} else {
load_global_cfg(&context).await;
load_global_cfg(&context);
}
let _ = register_plugins(&context);
@ -140,22 +140,22 @@ pub async fn run_script_file(options: Options) -> Result<(), Box<dyn Error>> {
.get(0)
.ok_or_else(|| ShellError::unexpected("Nu source code not available"))?;
run_script_standalone(script.get_code().to_string(), options.stdin, &context, true).await?;
run_script_standalone(script.get_code().to_string(), options.stdin, &context, true)?;
Ok(())
}
#[cfg(feature = "rustyline-support")]
pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn Error>> {
pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn Error>> {
let _ = configure_ctrl_c(&context);
// start time for running startup scripts (this metric includes loading of the cfg, but w/e)
let startup_commands_start_time = std::time::Instant::now();
if let Some(cfg) = options.config {
load_cfg_as_global_cfg(&context, PathBuf::from(cfg)).await;
load_cfg_as_global_cfg(&context, PathBuf::from(cfg));
} else {
load_global_cfg(&context).await;
load_global_cfg(&context);
}
// Store cmd duration in an env var
context.scope.add_env_var(
@ -196,7 +196,7 @@ pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box
};
//Check whether dir we start in contains local cfg file and if so load it.
load_local_cfg_if_present(&context).await;
load_local_cfg_if_present(&context);
// Give ourselves a scope to work in
context.scope.enter_scope();
@ -240,11 +240,11 @@ pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box
format!("\x1b[32m{}{}\x1b[m> ", cwd, current_branch())
} else {
let run_result = run_block(&prompt_block, &context, InputStream::empty()).await;
let run_result = run_block(&prompt_block, &context, InputStream::empty());
context.scope.exit_scope();
match run_result {
Ok(result) => match result.collect_string(Tag::unknown()).await {
Ok(result) => match result.collect_string(Tag::unknown()) {
Ok(string_result) => {
let errors = context.get_errors();
maybe_print_errors(&context, Text::from(prompt_line));
@ -302,16 +302,13 @@ pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box
let cmd_start_time = std::time::Instant::now();
let line = match convert_rustyline_result_to_string(readline) {
LineResult::Success(_) => {
process_script(
&session_text[line_start..],
&context,
false,
line_start,
true,
)
.await
}
LineResult::Success(_) => process_script(
&session_text[line_start..],
&context,
false,
line_start,
true,
),
x => x,
};
@ -404,11 +401,11 @@ pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box
Ok(())
}
pub async fn load_local_cfg_if_present(context: &EvaluationContext) {
pub fn load_local_cfg_if_present(context: &EvaluationContext) {
trace!("Loading local cfg if present");
match config::loadable_cfg_exists_in_dir(PathBuf::from(context.shell_manager.path())) {
Ok(Some(cfg_path)) => {
if let Err(err) = context.load_config(&ConfigPath::Local(cfg_path)).await {
if let Err(err) = context.load_config(&ConfigPath::Local(cfg_path)) {
context.host.lock().print_err(err, &Text::from(""))
}
}
@ -422,8 +419,8 @@ pub async fn load_local_cfg_if_present(context: &EvaluationContext) {
}
}
async fn load_cfg_as_global_cfg(context: &EvaluationContext, path: PathBuf) {
if let Err(err) = context.load_config(&ConfigPath::Global(path.clone())).await {
fn load_cfg_as_global_cfg(context: &EvaluationContext, path: PathBuf) {
if let Err(err) = context.load_config(&ConfigPath::Global(path.clone())) {
context.host.lock().print_err(err, &Text::from(""));
} else {
//TODO current commands assume to find path to global cfg file under config-path
@ -435,10 +432,10 @@ async fn load_cfg_as_global_cfg(context: &EvaluationContext, path: PathBuf) {
}
}
pub async fn load_global_cfg(context: &EvaluationContext) {
pub fn load_global_cfg(context: &EvaluationContext) {
match config::default_path() {
Ok(path) => {
load_cfg_as_global_cfg(context, path).await;
load_cfg_as_global_cfg(context, path);
}
Err(e) => {
context.host.lock().print_err(e, &Text::from(""));
@ -459,7 +456,7 @@ pub fn register_plugins(context: &EvaluationContext) -> Result<(), ShellError> {
Ok(())
}
pub async fn parse_and_eval(line: &str, ctx: &EvaluationContext) -> Result<String, ShellError> {
pub fn parse_and_eval(line: &str, ctx: &EvaluationContext) -> Result<String, ShellError> {
// FIXME: do we still need this?
let line = if let Some(s) = line.strip_suffix('\n') {
s
@ -477,10 +474,10 @@ pub async fn parse_and_eval(line: &str, ctx: &EvaluationContext) -> Result<Strin
let input_stream = InputStream::empty();
let result = run_block(&classified_block, ctx, input_stream).await;
let result = run_block(&classified_block, ctx, input_stream);
ctx.scope.exit_scope();
result?.collect_string(Tag::unknown()).await.map(|x| x.item)
result?.collect_string(Tag::unknown()).map(|x| x.item)
}
#[allow(dead_code)]

View File

@ -25,8 +25,6 @@ macro_rules! stream {
macro_rules! trace_out_stream {
(target: $target:tt, $desc:tt = $expr:expr) => {{
if log::log_enabled!(target: $target, log::Level::Trace) {
use futures::stream::StreamExt;
let objects = $expr.inspect(move |o| {
trace!(
target: $target,
@ -46,7 +44,6 @@ macro_rules! trace_out_stream {
}};
}
pub(crate) use futures::{Stream, StreamExt};
pub(crate) use nu_engine::Host;
#[allow(unused_imports)]
pub(crate) use nu_errors::ShellError;
@ -65,11 +62,11 @@ pub trait FromInputStream {
impl<T> FromInputStream for T
where
T: Stream<Item = nu_protocol::Value> + Send + 'static,
T: Iterator<Item = nu_protocol::Value> + Send + Sync + 'static,
{
fn from_input_stream(self) -> OutputStream {
OutputStream {
values: self.map(nu_protocol::ReturnSuccess::value).boxed(),
values: Box::new(self.map(nu_protocol::ReturnSuccess::value)),
}
}
}
@ -81,12 +78,12 @@ pub trait ToOutputStream {
impl<T, U> ToOutputStream for T
where
T: Stream<Item = U> + Send + 'static,
T: Iterator<Item = U> + Send + Sync + 'static,
U: Into<nu_protocol::ReturnValue>,
{
fn to_output_stream(self) -> OutputStream {
OutputStream {
values: self.map(|item| item.into()).boxed(),
values: Box::new(self.map(|item| item.into())),
}
}
}

View File

@ -27,8 +27,6 @@ nu-ansi-term = { version = "0.29.1", path = "../nu-ansi-term" }
Inflector = "0.11"
arboard = { version = "1.1.0", optional = true }
async-recursion = "0.3.2"
async-trait = "0.1.42"
base64 = "0.13.0"
bigdecimal = { version = "0.2.0", features = ["serde"] }
byte-unit = "4.0.9"
@ -51,8 +49,6 @@ encoding_rs = "0.8.28"
filesize = "0.2.0"
fs_extra = "1.2.0"
futures = { version = "0.3.12", features = ["compat", "io-compat"] }
futures-util = "0.3.12"
futures_codec = "0.4.1"
getset = "0.1.1"
glob = "0.3.0"
htmlescape = "0.3.1"

View File

@ -13,7 +13,6 @@ pub struct Arguments {
block: CapturedBlock,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"all?"
@ -31,8 +30,8 @@ impl WholeStreamCommand for Command {
"Find if the table rows matches the condition."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
all(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
all(args)
}
fn examples(&self) -> Vec<Example> {
@ -53,10 +52,10 @@ impl WholeStreamCommand for Command {
}
}
async fn all(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn all(args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let tag = args.call_info.name_tag.clone();
let (Arguments { block }, input) = args.process().await?;
let (Arguments { block }, input) = args.process()?;
let condition = {
if block.block.block.len() != 1 {
@ -99,28 +98,25 @@ async fn all(args: CommandArgs) -> Result<OutputStream, ShellError> {
ctx.scope.add_vars(&block.captured.entries);
ctx.scope.add_var("$it", row);
async move {
let condition = evaluate_baseline_expr(&condition, &*ctx).await.clone();
ctx.scope.exit_scope();
let condition = evaluate_baseline_expr(&condition, &*ctx);
ctx.scope.exit_scope();
let curr = acc?.drain_vec().await;
let curr = curr
.get(0)
.ok_or_else(|| ShellError::unexpected("No value to check with"))?;
let cond = curr.as_bool()?;
let curr = acc?.drain_vec();
let curr = curr
.get(0)
.ok_or_else(|| ShellError::unexpected("No value to check with"))?;
let cond = curr.as_bool()?;
match condition {
Ok(condition) => match condition.as_bool() {
Ok(b) => Ok(InputStream::one(
UntaggedValue::boolean(cond && b).into_value(&curr.tag),
)),
Err(e) => Err(e),
},
match condition {
Ok(condition) => match condition.as_bool() {
Ok(b) => Ok(InputStream::one(
UntaggedValue::boolean(cond && b).into_value(&curr.tag),
)),
Err(e) => Err(e),
}
},
Err(e) => Err(e),
}
})
.await?
})?
.to_output_stream())
}

View File

@ -14,7 +14,6 @@ struct AnsiArgs {
osc: Option<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"ansi"
@ -120,8 +119,8 @@ Format: #
]
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let (AnsiArgs { code, escape, osc }, _) = args.process().await?;
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let (AnsiArgs { code, escape, osc }, _) = args.process()?;
if let Some(e) = escape {
let esc_vec: Vec<char> = e.item.chars().collect();

View File

@ -15,7 +15,6 @@ struct Arguments {
rest: Vec<ColumnPath>,
}
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"ansi strip"
@ -32,8 +31,8 @@ impl WholeStreamCommand for SubCommand {
"strip ansi escape sequences from string"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
operate(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
operate(args)
}
fn examples(&self) -> Vec<Example> {
@ -45,8 +44,8 @@ impl WholeStreamCommand for SubCommand {
}
}
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rest }, input) = args.process().await?;
fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rest }, input) = args.process()?;
let column_paths: Vec<_> = rest;
Ok(input

View File

@ -13,7 +13,6 @@ pub struct Arguments {
block: CapturedBlock,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"any?"
@ -31,8 +30,8 @@ impl WholeStreamCommand for Command {
"Find if the table rows matches the condition."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
any(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
any(args)
}
fn examples(&self) -> Vec<Example> {
@ -53,10 +52,10 @@ impl WholeStreamCommand for Command {
}
}
async fn any(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn any(args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let tag = args.call_info.name_tag.clone();
let (Arguments { block }, input) = args.process().await?;
let (Arguments { block }, input) = args.process()?;
let condition = {
if block.block.block.len() != 1 {
@ -99,28 +98,25 @@ async fn any(args: CommandArgs) -> Result<OutputStream, ShellError> {
ctx.scope.add_vars(&block.captured.entries);
ctx.scope.add_var("$it", row);
async move {
let condition = evaluate_baseline_expr(&condition, &*ctx).await.clone();
ctx.scope.exit_scope();
let condition = evaluate_baseline_expr(&condition, &*ctx);
ctx.scope.exit_scope();
let curr = cond?.drain_vec().await;
let curr = curr
.get(0)
.ok_or_else(|| ShellError::unexpected("No value to check with"))?;
let cond = curr.as_bool()?;
let curr = cond?.drain_vec();
let curr = curr
.get(0)
.ok_or_else(|| ShellError::unexpected("No value to check with"))?;
let cond = curr.as_bool()?;
match condition {
Ok(condition) => match condition.as_bool() {
Ok(b) => Ok(InputStream::one(
UntaggedValue::boolean(cond || b).into_value(&curr.tag),
)),
Err(e) => Err(e),
},
match condition {
Ok(condition) => match condition.as_bool() {
Ok(b) => Ok(InputStream::one(
UntaggedValue::boolean(cond || b).into_value(&curr.tag),
)),
Err(e) => Err(e),
}
},
Err(e) => Err(e),
}
})
.await?
})?
.to_output_stream())
}

View File

@ -10,7 +10,6 @@ struct Arguments {
pub struct Command;
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"append"
@ -28,10 +27,10 @@ impl WholeStreamCommand for Command {
"Append a row to the table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { mut value }, input) = args.process().await?;
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { mut value }, input) = args.process()?;
let input: Vec<Value> = input.collect().await;
let input: Vec<Value> = input.collect();
if let Some(first) = input.get(0) {
value.tag = first.tag();
@ -48,18 +47,14 @@ impl WholeStreamCommand for Command {
}
}
Ok(futures::stream::iter(
input
.into_iter()
.chain(vec![value])
.map(ReturnSuccess::value),
)
.to_output_stream())
Ok(input
.into_iter()
.chain(vec![value])
.map(ReturnSuccess::value)
.to_output_stream())
}
fn examples(&self) -> Vec<Example> {
use nu_protocol::row;
vec![
Example {
description: "Add values to the end of the table",

View File

@ -4,7 +4,6 @@ use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
pub struct Autoenv;
#[async_trait]
impl WholeStreamCommand for Autoenv {
fn name(&self) -> &str {
"autoenv"
@ -26,7 +25,7 @@ The .nu-env file has the same format as your $HOME/nu/config.toml file. By loadi
fn signature(&self) -> Signature {
Signature::build("autoenv")
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(get_full_help(&Autoenv, &args.scope)).into_value(Tag::unknown()),
)))

View File

@ -8,7 +8,6 @@ use sha2::{Digest, Sha256};
use std::{fs, path::PathBuf};
pub struct AutoenvTrust;
#[async_trait]
impl WholeStreamCommand for AutoenvTrust {
fn name(&self) -> &str {
"autoenv trust"
@ -22,11 +21,11 @@ impl WholeStreamCommand for AutoenvTrust {
"Trust a .nu-env file in the current or given directory"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let ctx = EvaluationContext::from_args(&args);
let file_to_trust = match args.call_info.evaluate(&ctx).await?.args.nth(0) {
let file_to_trust = match args.call_info.evaluate(&ctx)?.args.nth(0) {
Some(Value {
value: UntaggedValue::Primitive(Primitive::String(ref path)),
tag: _,

View File

@ -8,7 +8,6 @@ use std::io::Read;
use std::{fs, path::PathBuf};
pub struct AutoenvUnTrust;
#[async_trait]
impl WholeStreamCommand for AutoenvUnTrust {
fn name(&self) -> &str {
"autoenv untrust"
@ -26,10 +25,10 @@ impl WholeStreamCommand for AutoenvUnTrust {
"Untrust a .nu-env file in the current or given directory"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let ctx = EvaluationContext::from_args(&args);
let file_to_untrust = match args.call_info.evaluate(&ctx).await?.args.nth(0) {
let file_to_untrust = match args.call_info.evaluate(&ctx)?.args.nth(0) {
Some(Value {
value: UntaggedValue::Primitive(Primitive::String(ref path)),
tag: _,

View File

@ -12,7 +12,6 @@ use std::sync::atomic::AtomicBool;
pub struct Command;
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"autoview"
@ -26,8 +25,8 @@ impl WholeStreamCommand for Command {
"View the contents of the pipeline as a table or list."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
autoview(RunnableContext::from_command_args(args)).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
autoview(RunnableContext::from_command_args(args))
}
fn examples(&self) -> Vec<Example> {
@ -71,7 +70,7 @@ impl RunnableContextWithoutInput {
}
}
pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellError> {
pub fn autoview(context: RunnableContext) -> Result<OutputStream, ShellError> {
let configuration = AutoViewConfiguration::new();
let binary = context.get_command("binaryview");
@ -84,21 +83,19 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
let term_width = context.host.lock().width();
let color_hm = get_color_config();
if let Some(x) = input_stream.next().await {
match input_stream.next().await {
if let Some(x) = input_stream.next() {
match input_stream.next() {
Some(y) => {
let ctrl_c = context.ctrl_c.clone();
let xy = vec![x, y];
let xy_stream = futures::stream::iter(xy)
.chain(input_stream)
.interruptible(ctrl_c);
let xy_stream = xy.into_iter().chain(input_stream).interruptible(ctrl_c);
let stream = InputStream::from_stream(xy_stream);
if let Some(table) = table {
let command_args = create_default_command_args(&context).with_input(stream);
let result = table.run(command_args).await?;
result.collect::<Vec<_>>().await;
let result = table.run(command_args)?;
let _ = result.collect::<Vec<_>>();
}
}
_ => {
@ -114,8 +111,8 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
);
let command_args =
create_default_command_args(&context).with_input(stream);
let result = text.run(command_args).await?;
result.collect::<Vec<_>>().await;
let result = text.run(command_args)?;
let _ = result.collect::<Vec<_>>();
} else {
out!("{}", s);
}
@ -196,8 +193,8 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
stream.push_back(x);
let command_args =
create_default_command_args(&context).with_input(stream);
let result = binary.run(command_args).await?;
result.collect::<Vec<_>>().await;
let result = binary.run(command_args)?;
let _ = result.collect::<Vec<_>>();
} else {
use pretty_hex::*;
out!("{:?}", b.hex_dump());
@ -262,8 +259,8 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
stream.push_back(x);
let command_args =
create_default_command_args(&context).with_input(stream);
let result = table.run(command_args).await?;
result.collect::<Vec<_>>().await;
let result = table.run(command_args)?;
let _ = result.collect::<Vec<_>>();
} else {
out!("{:?}", item);
}

View File

@ -23,7 +23,6 @@ struct BenchmarkArgs {
passthrough: Option<CapturedBlock>,
}
#[async_trait]
impl WholeStreamCommand for Benchmark {
fn name(&self) -> &str {
"benchmark"
@ -48,8 +47,8 @@ impl WholeStreamCommand for Benchmark {
"Runs a block and returns the time it took to execute it."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
benchmark(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
benchmark(args)
}
fn examples(&self) -> Vec<Example> {
@ -68,11 +67,11 @@ impl WholeStreamCommand for Benchmark {
}
}
async fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = raw_args.call_info.args.span;
let mut context = EvaluationContext::from_args(&raw_args);
let scope = raw_args.scope.clone();
let (BenchmarkArgs { block, passthrough }, input) = raw_args.process().await?;
let (BenchmarkArgs { block, passthrough }, input) = raw_args.process()?;
let env = scope.get_env_vars();
let name = generate_free_name(&env);
@ -82,15 +81,15 @@ async fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let start_time = Instant::now();
// #[cfg(feature = "rich-benchmark")]
// let start = time().await;
// let start = time();
context.scope.enter_scope();
let result = run_block(&block.block, &context, input).await;
let result = run_block(&block.block, &context, input);
context.scope.exit_scope();
let output = result?.into_vec().await;
let output = result?.into_vec();
// #[cfg(feature = "rich-benchmark")]
// let end = time().await;
// let end = time();
let end_time = Instant::now();
context.clear_errors();
@ -102,7 +101,7 @@ async fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let real_time = into_big_int(end_time - start_time);
indexmap.insert("real time".to_string(), real_time);
benchmark_output(indexmap, output, passthrough, &tag, &mut context).await
benchmark_output(indexmap, output, passthrough, &tag, &mut context)
}
// return advanced stats
// #[cfg(feature = "rich-benchmark")]
@ -121,7 +120,7 @@ async fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
// let idle_time = into_big_int(end.idle() - start.idle());
// indexmap.insert("idle time".to_string(), idle_time);
// benchmark_output(indexmap, output, passthrough, &tag, &mut context).await
// benchmark_output(indexmap, output, passthrough, &tag, &mut context)
// } else {
// Err(ShellError::untagged_runtime_error(
// "Could not retrieve CPU time",
@ -129,7 +128,7 @@ async fn benchmark(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
// }
}
async fn benchmark_output<T, Output>(
fn benchmark_output<T, Output>(
indexmap: IndexMap<String, BigInt>,
block_output: Output,
passthrough: Option<CapturedBlock>,
@ -155,7 +154,7 @@ where
let time_block = add_implicit_autoview(time_block.block);
context.scope.enter_scope();
let result = run_block(&time_block, context, benchmark_output).await;
let result = run_block(&time_block, context, benchmark_output);
context.scope.exit_scope();
result?;
context.clear_errors();

View File

@ -12,7 +12,6 @@ pub struct BuildStringArgs {
pub struct BuildString;
#[async_trait]
impl WholeStreamCommand for BuildString {
fn name(&self) -> &str {
"build-string"
@ -27,9 +26,9 @@ impl WholeStreamCommand for BuildString {
"Builds a string from the arguments."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (BuildStringArgs { rest }, _) = args.process().await?;
let (BuildStringArgs { rest }, _) = args.process()?;
let mut output_string = String::new();

View File

@ -7,7 +7,6 @@ use nu_protocol::{Dictionary, Signature, SyntaxShape, UntaggedValue, Value};
pub struct Cal;
#[async_trait]
impl WholeStreamCommand for Cal {
fn name(&self) -> &str {
"cal"
@ -41,8 +40,8 @@ impl WholeStreamCommand for Cal {
"Display a calendar."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
cal(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
cal(args)
}
fn examples(&self) -> Vec<Example> {
@ -66,8 +65,8 @@ impl WholeStreamCommand for Cal {
}
}
pub async fn cal(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
pub fn cal(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let mut calendar_vec_deque = VecDeque::new();
let tag = args.call_info.name_tag.clone();
@ -102,7 +101,7 @@ pub async fn cal(args: CommandArgs) -> Result<OutputStream, ShellError> {
current_day_option,
)?;
Ok(futures::stream::iter(calendar_vec_deque).to_output_stream())
Ok(calendar_vec_deque.into_iter().to_output_stream())
}
fn get_invalid_year_shell_error(year_tag: &Tag) -> ShellError {

View File

@ -7,7 +7,6 @@ use nu_protocol::{Signature, SyntaxShape};
pub struct Cd;
#[async_trait]
impl WholeStreamCommand for Cd {
fn name(&self) -> &str {
"cd"
@ -25,10 +24,10 @@ impl WholeStreamCommand for Cd {
"Change to a new path."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let shell_manager = args.shell_manager.clone();
let (args, _): (CdArgs, _) = args.process().await?;
let (args, _): (CdArgs, _) = args.process()?;
shell_manager.cd(args, name)
}

View File

@ -13,7 +13,6 @@ struct CharArgs {
unicode: bool,
}
#[async_trait]
impl WholeStreamCommand for Char {
fn name(&self) -> &str {
"char"
@ -65,7 +64,7 @@ impl WholeStreamCommand for Char {
]
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let (
CharArgs {
name,
@ -73,7 +72,7 @@ impl WholeStreamCommand for Char {
unicode,
},
_,
) = args.process().await?;
) = args.process()?;
if unicode {
if !rest.is_empty() {

View File

@ -6,7 +6,6 @@ use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
#[derive(Clone)]
pub struct Chart;
#[async_trait]
impl WholeStreamCommand for Chart {
fn name(&self) -> &str {
"chart"
@ -20,7 +19,7 @@ impl WholeStreamCommand for Chart {
"Displays charts."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
if args.scope.get_command("chart bar").is_none() {
return Err(ShellError::untagged_runtime_error(
"nu_plugin_chart not installed.",

View File

@ -1,16 +1,14 @@
use crate::futures::ThreadedReceiver;
use crate::prelude::*;
use nu_engine::evaluate_baseline_expr;
use nu_engine::{evaluate_baseline_expr, BufCodecReader};
use nu_engine::{MaybeTextCodec, StringOrBinary};
use std::borrow::Cow;
use std::io::Write;
use std::ops::Deref;
use std::process::{Command, Stdio};
use std::sync::mpsc;
use std::{borrow::Cow, io::BufReader};
use futures::executor::block_on_stream;
use futures_codec::FramedRead;
use log::trace;
use nu_errors::ShellError;
@ -18,9 +16,8 @@ use nu_protocol::hir::Expression;
use nu_protocol::hir::{ExternalCommand, ExternalRedirection};
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
use nu_source::Tag;
use nu_stream::trace_stream;
pub(crate) async fn run_external_command(
pub(crate) fn run_external_command(
command: ExternalCommand,
context: &mut EvaluationContext,
input: InputStream,
@ -36,10 +33,10 @@ pub(crate) async fn run_external_command(
));
}
run_with_stdin(command, context, input, external_redirection).await
run_with_stdin(command, context, input, external_redirection)
}
async fn run_with_stdin(
fn run_with_stdin(
command: ExternalCommand,
context: &mut EvaluationContext,
input: InputStream,
@ -47,12 +44,10 @@ async fn run_with_stdin(
) -> Result<InputStream, ShellError> {
let path = context.shell_manager.path();
let input = trace_stream!(target: "nu::trace_stream::external::stdin", "input" = input);
let mut command_args = vec![];
for arg in command.args.iter() {
let is_literal = matches!(arg.expr, Expression::Literal(_));
let value = evaluate_baseline_expr(arg, context).await?;
let value = evaluate_baseline_expr(arg, context)?;
// Skip any arguments that don't really exist, treating them as optional
// FIXME: we may want to preserve the gap in the future, though it's hard to say
@ -219,7 +214,7 @@ fn spawn(
.take()
.expect("Internal error: could not get stdin pipe for external command");
for value in block_on_stream(input) {
for value in input {
match &value.value {
UntaggedValue::Primitive(Primitive::Nothing) => continue,
UntaggedValue::Primitive(Primitive::String(s)) => {
@ -274,10 +269,12 @@ fn spawn(
return Err(());
};
let file = futures::io::AllowStdIo::new(stdout);
let stream = FramedRead::new(file, MaybeTextCodec::default());
// let file = futures::io::AllowStdIo::new(stdout);
// let stream = FramedRead::new(file, MaybeTextCodec::default());
let buf_read = BufReader::new(stdout);
let buf_codec = BufCodecReader::new(buf_read, MaybeTextCodec::default());
for line in block_on_stream(stream) {
for line in buf_codec {
match line {
Ok(line) => match line {
StringOrBinary::String(s) => {
@ -345,10 +342,12 @@ fn spawn(
return Err(());
};
let file = futures::io::AllowStdIo::new(stderr);
let stream = FramedRead::new(file, MaybeTextCodec::default());
// let file = futures::io::AllowStdIo::new(stderr);
// let stream = FramedRead::new(file, MaybeTextCodec::default());
let buf_reader = BufReader::new(stderr);
let buf_codec = BufCodecReader::new(buf_reader, MaybeTextCodec::default());
for line in block_on_stream(stream) {
for line in buf_codec {
match line {
Ok(line) => match line {
StringOrBinary::String(s) => {
@ -506,16 +505,13 @@ mod tests {
#[cfg(feature = "which")]
use super::{run_external_command, InputStream};
#[cfg(feature = "which")]
use futures::executor::block_on;
#[cfg(feature = "which")]
use nu_engine::basic_evaluation_context;
#[cfg(feature = "which")]
use nu_errors::ShellError;
#[cfg(feature = "which")]
use nu_test_support::commands::ExternalBuilder;
// async fn read(mut stream: OutputStream) -> Option<Value> {
// match stream.try_next().await {
// fn read(mut stream: OutputStream) -> Option<Value> {
// match stream.try_next() {
// Ok(val) => {
// if let Some(val) = val {
// val.raw_value()
@ -528,7 +524,7 @@ mod tests {
// }
#[cfg(feature = "which")]
async fn non_existent_run() -> Result<(), ShellError> {
fn non_existent_run() {
use nu_protocol::hir::ExternalRedirection;
let cmd = ExternalBuilder::for_name("i_dont_exist.exe").build();
@ -536,24 +532,18 @@ mod tests {
let mut ctx =
basic_evaluation_context().expect("There was a problem creating a basic context.");
assert!(
run_external_command(cmd, &mut ctx, input, ExternalRedirection::Stdout)
.await
.is_err()
);
Ok(())
assert!(run_external_command(cmd, &mut ctx, input, ExternalRedirection::Stdout).is_err());
}
// async fn failure_run() -> Result<(), ShellError> {
// fn failure_run() -> Result<(), ShellError> {
// let cmd = ExternalBuilder::for_name("fail").build();
// let mut ctx = crate::cli::basic_evaluation_context().expect("There was a problem creating a basic context.");
// let stream = run_external_command(cmd, &mut ctx, None, false)
// .await?
// ?
// .expect("There was a problem running the external command.");
// match read(stream.into()).await {
// match read(stream.into()) {
// Some(Value {
// value: UntaggedValue::Error(_),
// ..
@ -571,8 +561,8 @@ mod tests {
#[cfg(feature = "which")]
#[test]
fn identifies_command_not_found() -> Result<(), ShellError> {
block_on(non_existent_run())
fn identifies_command_not_found() {
non_existent_run()
}
#[test]

View File

@ -6,7 +6,6 @@ use std::process::Command;
pub struct Clear;
#[async_trait]
impl WholeStreamCommand for Clear {
fn name(&self) -> &str {
"clear"
@ -20,7 +19,7 @@ impl WholeStreamCommand for Clear {
"Clears the terminal."
}
async fn run(&self, _: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, _: CommandArgs) -> Result<OutputStream, ShellError> {
if cfg!(windows) {
Command::new("cmd")
.args(&["/C", "cls"])

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use futures::stream::StreamExt;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{Signature, Value};
@ -8,7 +8,6 @@ use arboard::Clipboard;
pub struct Clip;
#[async_trait]
impl WholeStreamCommand for Clip {
fn name(&self) -> &str {
"clip"
@ -22,8 +21,8 @@ impl WholeStreamCommand for Clip {
"Copy the contents of the pipeline to the copy/paste buffer."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
clip(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
clip(args)
}
fn examples(&self) -> Vec<Example> {
@ -42,10 +41,10 @@ impl WholeStreamCommand for Clip {
}
}
pub async fn clip(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn clip(args: CommandArgs) -> Result<OutputStream, ShellError> {
let input = args.input;
let name = args.call_info.name_tag.clone();
let values: Vec<Value> = input.collect().await;
let values: Vec<Value> = input.collect();
if let Ok(mut clip_context) = Clipboard::new() {
let mut new_copy_data = String::new();

View File

@ -1,6 +1,5 @@
use crate::prelude::*;
use futures::future;
use futures::stream::StreamExt;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
@ -13,7 +12,6 @@ pub struct CompactArgs {
rest: Vec<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for Compact {
fn name(&self) -> &str {
"compact"
@ -27,8 +25,8 @@ impl WholeStreamCommand for Compact {
"Creates a table with non-empty rows."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
compact(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
compact(args)
}
fn examples(&self) -> Vec<Example> {
@ -40,11 +38,11 @@ impl WholeStreamCommand for Compact {
}
}
pub async fn compact(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (CompactArgs { rest: columns }, input) = args.process().await?;
pub fn compact(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (CompactArgs { rest: columns }, input) = args.process()?;
Ok(input
.filter_map(move |item| {
future::ready(if columns.is_empty() {
if columns.is_empty() {
if !item.is_empty() {
Some(ReturnSuccess::value(item))
} else {
@ -67,7 +65,7 @@ pub async fn compact(args: CommandArgs) -> Result<OutputStream, ShellError> {
}
_ => None,
}
})
}
})
.to_output_stream())
}

View File

@ -5,7 +5,6 @@ use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"config clear"
@ -19,8 +18,8 @@ impl WholeStreamCommand for SubCommand {
"clear the config"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
clear(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
clear(args)
}
fn examples(&self) -> Vec<Example> {
@ -32,7 +31,7 @@ impl WholeStreamCommand for SubCommand {
}
}
pub async fn clear(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn clear(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_span = args.call_info.name_tag.clone();
let path = match args.scope.get_var("config-path") {

View File

@ -7,7 +7,6 @@ use nu_stream::OutputStream;
pub struct Command;
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"config"
@ -21,22 +20,22 @@ impl WholeStreamCommand for Command {
"Configuration management."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag;
if let Some(global_cfg) = &args.configs.lock().global_config {
let result = global_cfg.vars.clone();
Ok(futures::stream::iter(vec![ReturnSuccess::value(
Ok(vec![ReturnSuccess::value(
UntaggedValue::Row(result.into()).into_value(name),
)])
)]
.into_iter()
.to_output_stream())
} else {
Ok(
futures::stream::iter(vec![ReturnSuccess::value(UntaggedValue::Error(
ShellError::untagged_runtime_error("No global config found!"),
))])
.to_output_stream(),
)
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
ShellError::untagged_runtime_error("No global config found!"),
))]
.into_iter()
.to_output_stream())
}
}
}

View File

@ -12,7 +12,6 @@ pub struct Arguments {
column_path: ColumnPath,
}
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"config get"
@ -30,8 +29,8 @@ impl WholeStreamCommand for SubCommand {
"Gets a value from the config"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
get(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
get(args)
}
fn examples(&self) -> Vec<Example> {
@ -43,10 +42,10 @@ impl WholeStreamCommand for SubCommand {
}
}
pub async fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let scope = args.scope.clone();
let (Arguments { column_path }, _) = args.process().await?;
let (Arguments { column_path }, _) = args.process()?;
let path = match scope.get_var("config-path") {
Some(Value {
@ -70,7 +69,7 @@ pub async fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map(|x| ReturnSuccess::value(x.clone()))
.collect();
futures::stream::iter(list).to_output_stream()
list.into_iter().to_output_stream()
}
x => OutputStream::one(ReturnSuccess::value(x)),
})

View File

@ -5,7 +5,6 @@ use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"config path"
@ -19,8 +18,8 @@ impl WholeStreamCommand for SubCommand {
"return the path to the config file"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
path(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
path(args)
}
fn examples(&self) -> Vec<Example> {
@ -32,7 +31,7 @@ impl WholeStreamCommand for SubCommand {
}
}
pub async fn path(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn path(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(OutputStream::one(ReturnSuccess::value(
match args.scope.get_var("config-path") {
Some(

View File

@ -11,7 +11,6 @@ pub struct Arguments {
remove: Tagged<String>,
}
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"config remove"
@ -29,8 +28,8 @@ impl WholeStreamCommand for SubCommand {
"Removes a value from the config"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
remove(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
remove(args)
}
fn examples(&self) -> Vec<Example> {
@ -42,10 +41,10 @@ impl WholeStreamCommand for SubCommand {
}
}
pub async fn remove(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn remove(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_span = args.call_info.name_tag.clone();
let scope = args.scope.clone();
let (Arguments { remove }, _) = args.process().await?;
let (Arguments { remove }, _) = args.process()?;
let path = match scope.get_var("config-path") {
Some(Value {
@ -62,9 +61,10 @@ pub async fn remove(args: CommandArgs) -> Result<OutputStream, ShellError> {
if result.contains_key(&key) {
result.swap_remove(&key);
config::write(&result, &path)?;
Ok(futures::stream::iter(vec![ReturnSuccess::value(
Ok(vec![ReturnSuccess::value(
UntaggedValue::Row(result.into()).into_value(remove.tag()),
)])
)]
.into_iter()
.to_output_stream())
} else {
Err(ShellError::labeled_error(

View File

@ -13,7 +13,6 @@ pub struct Arguments {
value: Value,
}
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"config set"
@ -29,8 +28,8 @@ impl WholeStreamCommand for SubCommand {
"Sets a value in the config"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
set(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
set(args)
}
fn examples(&self) -> Vec<Example> {
@ -59,7 +58,7 @@ impl WholeStreamCommand for SubCommand {
}
}
pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let ctx = EvaluationContext::from_args(&args);
let scope = args.scope.clone();
@ -69,7 +68,7 @@ pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
mut value,
},
_,
) = args.process().await?;
) = args.process()?;
let path = match scope.get_var("config-path") {
Some(Value {
@ -96,8 +95,7 @@ pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write(&changes.entries, &path)?;
ctx.reload_config(&ConfigPath::Global(
path.expect("Global config path is always some"),
))
.await?;
))?;
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::Row(changes).into_value(name),

View File

@ -13,7 +13,6 @@ pub struct Arguments {
set_into: Tagged<String>,
}
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"config set_into"
@ -31,8 +30,8 @@ impl WholeStreamCommand for SubCommand {
"Sets a value in the config"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
set_into(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
set_into(args)
}
fn examples(&self) -> Vec<Example> {
@ -44,11 +43,11 @@ impl WholeStreamCommand for SubCommand {
}
}
pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let ctx = EvaluationContext::from_args(&args);
let scope = args.scope.clone();
let (Arguments { set_into: v }, input) = args.process().await?;
let (Arguments { set_into: v }, input) = args.process()?;
let path = match scope.get_var("config-path") {
Some(Value {
@ -60,7 +59,7 @@ pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = nu_data::config::read(&name, &path)?;
let rows: Vec<Value> = input.collect().await;
let rows: Vec<Value> = input.collect();
let key = v.to_string();
Ok(if rows.is_empty() {
@ -78,8 +77,7 @@ pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write(&result, &path)?;
ctx.reload_config(&ConfigPath::Global(
path.expect("Global config path is always some"),
))
.await?;
))?;
OutputStream::one(ReturnSuccess::value(
UntaggedValue::Row(result.into()).into_value(name),
@ -93,8 +91,7 @@ pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write(&result, &path)?;
ctx.reload_config(&ConfigPath::Global(
path.expect("Global config path is always some"),
))
.await?;
))?;
OutputStream::one(ReturnSuccess::value(
UntaggedValue::Row(result.into()).into_value(name),

View File

@ -5,7 +5,6 @@ use nu_protocol::{Signature, SyntaxShape};
pub struct Cpy;
#[async_trait]
impl WholeStreamCommand for Cpy {
fn name(&self) -> &str {
"cp"
@ -26,10 +25,10 @@ impl WholeStreamCommand for Cpy {
"Copy files."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let shell_manager = args.shell_manager.clone();
let name = args.call_info.name_tag.clone();
let (args, _) = args.process().await?;
let (args, _) = args.process()?;
shell_manager.cp(args, name)
}

View File

@ -5,7 +5,6 @@ use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
pub struct Command;
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"date"
@ -19,7 +18,7 @@ impl WholeStreamCommand for Command {
"Apply date function."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
)))

View File

@ -15,7 +15,6 @@ pub struct FormatArgs {
table: bool,
}
#[async_trait]
impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date format"
@ -31,8 +30,8 @@ impl WholeStreamCommand for Date {
"Format a given date using the given format string."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
format(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
format(args)
}
fn examples(&self) -> Vec<Example> {
@ -51,9 +50,9 @@ impl WholeStreamCommand for Date {
}
}
pub async fn format(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn format(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (FormatArgs { format, table }, input) = args.process().await?;
let (FormatArgs { format, table }, input) = args.process()?;
Ok(input
.map(move |value| match value {

View File

@ -7,7 +7,6 @@ use nu_protocol::{Dictionary, ReturnSuccess, Signature, UntaggedValue};
pub struct Date;
#[async_trait]
impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date list-timezone"
@ -21,8 +20,8 @@ impl WholeStreamCommand for Date {
"List supported time zones."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
list_timezone(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
list_timezone(args)
}
fn examples(&self) -> Vec<Example> {
@ -41,8 +40,8 @@ impl WholeStreamCommand for Date {
}
}
async fn list_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn list_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.call_info.name_tag.clone();
let list = TZ_VARIANTS.iter().map(move |tz| {
@ -58,7 +57,7 @@ async fn list_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
))
});
Ok(futures::stream::iter(list).to_output_stream())
Ok(list.into_iter().to_output_stream())
}
#[cfg(test)]

View File

@ -6,7 +6,6 @@ use nu_protocol::{Signature, UntaggedValue};
pub struct Date;
#[async_trait]
impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date now"
@ -20,13 +19,13 @@ impl WholeStreamCommand for Date {
"Get the current date."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
now(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
now(args)
}
}
pub async fn now(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
pub fn now(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.call_info.name_tag.clone();
let now: DateTime<Local> = Local::now();

View File

@ -7,7 +7,6 @@ use nu_protocol::{Dictionary, Primitive, ReturnSuccess, Signature, UntaggedValue
pub struct Date;
#[async_trait]
impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date to-table"
@ -21,8 +20,8 @@ impl WholeStreamCommand for Date {
"Print the date in a structured table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
to_table(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
to_table(args)
}
fn examples(&self) -> Vec<Example> {
@ -34,8 +33,8 @@ impl WholeStreamCommand for Date {
}
}
async fn to_table(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn to_table(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.call_info.name_tag.clone();
let input = args.input;

View File

@ -12,7 +12,6 @@ struct DateToTimeZoneArgs {
timezone: Tagged<String>,
}
#[async_trait]
impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date to-timezone"
@ -34,8 +33,8 @@ impl WholeStreamCommand for Date {
"Use 'date list-timezone' to list all supported time zones."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
to_timezone(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
to_timezone(args)
}
fn examples(&self) -> Vec<Example> {
@ -59,9 +58,9 @@ impl WholeStreamCommand for Date {
}
}
async fn to_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn to_timezone(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (DateToTimeZoneArgs { timezone }, input) = args.process().await?;
let (DateToTimeZoneArgs { timezone }, input) = args.process()?;
Ok(input
.map(move |value| match value {

View File

@ -8,7 +8,6 @@ use nu_protocol::Signature;
pub struct Date;
#[async_trait]
impl WholeStreamCommand for Date {
fn name(&self) -> &str {
"date utc"
@ -22,13 +21,13 @@ impl WholeStreamCommand for Date {
"return the current date in utc."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
utc(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
utc(args)
}
}
pub async fn utc(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
pub fn utc(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.call_info.name_tag.clone();
let no_fmt = "".to_string();

View File

@ -10,7 +10,6 @@ pub struct DebugArgs {
raw: bool,
}
#[async_trait]
impl WholeStreamCommand for Debug {
fn name(&self) -> &str {
"debug"
@ -24,13 +23,13 @@ impl WholeStreamCommand for Debug {
"Print the Rust debug representation of the values."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
debug_value(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
debug_value(args)
}
}
async fn debug_value(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (DebugArgs { raw }, input) = args.process().await?;
fn debug_value(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (DebugArgs { raw }, input) = args.process()?;
Ok(input
.map(move |v| {
if raw {

View File

@ -14,7 +14,6 @@ pub struct DefArgs {
pub block: CapturedBlock,
}
#[async_trait]
impl WholeStreamCommand for Def {
fn name(&self) -> &str {
"def"
@ -35,7 +34,7 @@ impl WholeStreamCommand for Def {
"Create a command and set it to a definition."
}
async fn run(&self, _args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, _args: CommandArgs) -> Result<OutputStream, ShellError> {
// Currently, we don't do anything here because we should have already
// installed the definition as we entered the scope
// We just create a command so that we can get proper coloring

View File

@ -13,7 +13,6 @@ struct DefaultArgs {
pub struct Default;
#[async_trait]
impl WholeStreamCommand for Default {
fn name(&self) -> &str {
"default"
@ -33,8 +32,8 @@ impl WholeStreamCommand for Default {
"Sets a default row's column if missing."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
default(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
default(args)
}
fn examples(&self) -> Vec<Example> {
@ -46,8 +45,8 @@ impl WholeStreamCommand for Default {
}
}
async fn default(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (DefaultArgs { column, value }, input) = args.process().await?;
fn default(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (DefaultArgs { column, value }, input) = args.process()?;
Ok(input
.map(move |item| {

View File

@ -9,7 +9,6 @@ pub struct Describe;
#[derive(Deserialize)]
pub struct DescribeArgs {}
#[async_trait]
impl WholeStreamCommand for Describe {
fn name(&self) -> &str {
"describe"
@ -23,12 +22,12 @@ impl WholeStreamCommand for Describe {
"Describes the objects in the stream."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
describe(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
describe(args)
}
}
pub async fn describe(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn describe(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(args
.input
.map(|row| {

View File

@ -12,7 +12,6 @@ struct DoArgs {
ignore_errors: bool,
}
#[async_trait]
impl WholeStreamCommand for Do {
fn name(&self) -> &str {
"do"
@ -32,8 +31,8 @@ impl WholeStreamCommand for Do {
"Runs a block, optionally ignoring errors."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
do_(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
do_(args)
}
fn examples(&self) -> Vec<Example> {
@ -52,7 +51,7 @@ impl WholeStreamCommand for Do {
}
}
async fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let external_redirection = raw_args.call_info.args.external_redirection;
let context = EvaluationContext::from_args(&raw_args);
@ -62,7 +61,7 @@ async fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
mut block,
},
input,
) = raw_args.process().await?;
) = raw_args.process()?;
let block_redirection = match external_redirection {
ExternalRedirection::None => {
@ -84,7 +83,7 @@ async fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
block.block.set_redirect(block_redirection);
context.scope.enter_scope();
let result = run_block(&block.block, &context, input).await;
let result = run_block(&block.block, &context, input);
context.scope.exit_scope();
if ignore_errors {
@ -93,9 +92,9 @@ async fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
match result {
Ok(mut stream) => {
let output = stream.drain_vec().await;
let output = stream.drain_vec();
context.clear_errors();
Ok(futures::stream::iter(output).to_output_stream())
Ok(output.into_iter().to_output_stream())
}
Err(_) => Ok(OutputStream::empty()),
}

View File

@ -12,7 +12,6 @@ pub struct Arguments {
columns: Option<Tagged<u64>>,
}
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"drop column"
@ -30,12 +29,12 @@ impl WholeStreamCommand for SubCommand {
"Remove the last number of columns. If you want to remove columns by name, try 'reject'."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
drop(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
drop(args)
}
fn examples(&self) -> Vec<Example> {
use nu_protocol::{row, Value};
use nu_protocol::Value;
vec![Example {
description: "Remove the last column of a table",
@ -48,8 +47,8 @@ impl WholeStreamCommand for SubCommand {
}
}
async fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { columns }, input) = args.process().await?;
fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { columns }, input) = args.process()?;
let to_drop = if let Some(quantity) = columns {
*quantity as usize

View File

@ -11,7 +11,6 @@ pub struct Arguments {
rows: Option<Tagged<u64>>,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"drop"
@ -29,8 +28,8 @@ impl WholeStreamCommand for Command {
"Remove the last number of rows or columns."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
drop(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
drop(args)
}
fn examples(&self) -> Vec<Example> {
@ -52,9 +51,9 @@ impl WholeStreamCommand for Command {
}
}
async fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rows }, input) = args.process().await?;
let v: Vec<_> = input.into_vec().await;
fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rows }, input) = args.process()?;
let v: Vec<_> = input.into_vec();
let rows_to_drop = if let Some(quantity) = rows {
*quantity as usize
@ -63,7 +62,7 @@ async fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
};
Ok(if rows_to_drop == 0 {
futures::stream::iter(v).to_output_stream()
v.into_iter().to_output_stream()
} else {
let k = if v.len() < rows_to_drop {
0
@ -73,6 +72,6 @@ async fn drop(args: CommandArgs) -> Result<OutputStream, ShellError> {
let iter = v.into_iter().take(k);
futures::stream::iter(iter).to_output_stream()
iter.to_output_stream()
})
}

View File

@ -28,7 +28,6 @@ pub struct DuArgs {
min_size: Option<Tagged<u64>>,
}
#[async_trait]
impl WholeStreamCommand for Du {
fn name(&self) -> &str {
NAME
@ -71,8 +70,8 @@ impl WholeStreamCommand for Du {
"Find disk usage sizes of specified items."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
du(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
du(args)
}
fn examples(&self) -> Vec<Example> {
@ -84,12 +83,12 @@ impl WholeStreamCommand for Du {
}
}
async fn du(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn du(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let ctrl_c = args.ctrl_c.clone();
let ctrl_c_copy = ctrl_c.clone();
let (args, _): (DuArgs, _) = args.process().await?;
let (args, _): (DuArgs, _) = args.process()?;
let exclude = args.exclude.map_or(Ok(None), move |x| {
Pattern::new(&x.item)
.map(Option::Some)
@ -131,7 +130,7 @@ async fn du(args: CommandArgs) -> Result<OutputStream, ShellError> {
all,
};
let inp = futures::stream::iter(paths);
let inp = paths;
Ok(inp
.flat_map(move |path| match path {
@ -146,9 +145,9 @@ async fn du(args: CommandArgs) -> Result<OutputStream, ShellError> {
output.push(Ok(ReturnSuccess::Value(v.into())));
}
}
futures::stream::iter(output)
output
}
Err(e) => futures::stream::iter(vec![Err(e)]),
Err(e) => vec![Err(e)],
})
.interruptible(ctrl_c_copy)
.to_output_stream())

View File

@ -2,7 +2,6 @@ use crate::prelude::*;
use nu_engine::run_block;
use nu_engine::WholeStreamCommand;
use futures::stream::once;
use nu_errors::ShellError;
use nu_protocol::{
hir::CapturedBlock, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
@ -17,7 +16,6 @@ pub struct EachArgs {
numbered: Tagged<bool>,
}
#[async_trait]
impl WholeStreamCommand for Each {
fn name(&self) -> &str {
"each"
@ -37,8 +35,8 @@ impl WholeStreamCommand for Each {
"Run a block on each row of the table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
each(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
each(args)
}
fn examples(&self) -> Vec<Example> {
@ -67,7 +65,7 @@ impl WholeStreamCommand for Each {
}
}
pub async fn process_row(
pub fn process_row(
captured_block: Arc<Box<CapturedBlock>>,
context: Arc<EvaluationContext>,
input: Value,
@ -80,7 +78,7 @@ pub async fn process_row(
let input_stream = if !captured_block.block.params.positional.is_empty() {
InputStream::empty()
} else {
once(async { Ok(input_clone) }).to_input_stream()
vec![Ok(input_clone)].into_iter().to_input_stream()
};
context.scope.enter_scope();
@ -95,7 +93,7 @@ pub async fn process_row(
context.scope.add_var("$it", input);
}
let result = run_block(&captured_block.block, &*context, input_stream).await;
let result = run_block(&captured_block.block, &*context, input_stream);
context.scope.exit_scope();
@ -110,40 +108,36 @@ pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
dict.into_value()
}
async fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let context = Arc::new(EvaluationContext::from_args(&raw_args));
let (each_args, input): (EachArgs, _) = raw_args.process().await?;
let (each_args, input): (EachArgs, _) = raw_args.process()?;
let block = Arc::new(Box::new(each_args.block));
if each_args.numbered.item {
Ok(input
.enumerate()
.then(move |input| {
.map(move |input| {
let block = block.clone();
let context = context.clone();
let row = make_indexed_item(input.0, input.1);
async {
match process_row(block, context, row).await {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
match process_row(block, context, row) {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
})
.flatten()
.to_output_stream())
} else {
Ok(input
.then(move |input| {
.map(move |input| {
let block = block.clone();
let context = context.clone();
async {
match process_row(block, context, input).await {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
match process_row(block, context, input) {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
})
.flatten()

View File

@ -17,7 +17,6 @@ pub struct EachGroupArgs {
//numbered: Tagged<bool>,
}
#[async_trait]
impl WholeStreamCommand for EachGroup {
fn name(&self) -> &str {
"each group"
@ -45,16 +44,54 @@ impl WholeStreamCommand for EachGroup {
}]
}
async fn run(&self, raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let context = Arc::new(EvaluationContext::from_args(&raw_args));
let (each_args, input): (EachGroupArgs, _) = raw_args.process().await?;
let (each_args, input): (EachGroupArgs, _) = raw_args.process()?;
let block = Arc::new(Box::new(each_args.block));
Ok(input
.chunks(each_args.group_size.item)
.then(move |input| run_block_on_vec(input, block.clone(), context.clone()))
.flatten()
.to_output_stream())
let each_group_iterator = EachGroupIterator {
block,
context,
group_size: each_args.group_size.item,
input,
};
Ok(each_group_iterator.flatten().to_output_stream())
}
}
struct EachGroupIterator {
block: Arc<Box<CapturedBlock>>,
context: Arc<EvaluationContext>,
group_size: usize,
input: InputStream,
}
impl Iterator for EachGroupIterator {
type Item = OutputStream;
fn next(&mut self) -> Option<Self::Item> {
let mut group = vec![];
let mut current_count = 0;
while let Some(next) = self.input.next() {
group.push(next);
current_count += 1;
if current_count >= self.group_size {
break;
}
}
if group.is_empty() {
return None;
}
Some(run_block_on_vec(
group,
self.block.clone(),
self.context.clone(),
))
}
}
@ -62,43 +99,43 @@ pub(crate) fn run_block_on_vec(
input: Vec<Value>,
block: Arc<Box<CapturedBlock>>,
context: Arc<EvaluationContext>,
) -> impl Future<Output = OutputStream> {
) -> OutputStream {
let value = Value {
value: UntaggedValue::Table(input),
tag: Tag::unknown(),
};
async {
match process_row(block, context, value).await {
Ok(s) => {
// We need to handle this differently depending on whether process_row
// returned just 1 value or if it returned multiple as a stream.
let vec = s.collect::<Vec<_>>().await;
match process_row(block, context, value) {
Ok(s) => {
// We need to handle this differently depending on whether process_row
// returned just 1 value or if it returned multiple as a stream.
let vec = s.collect::<Vec<_>>();
// If it returned just one value, just take that value
if vec.len() == 1 {
return OutputStream::one(vec.into_iter().next().expect(
"This should be impossible, we just checked that vec.len() == 1.",
));
}
// If it returned multiple values, we need to put them into a table and
// return that.
let result = vec.into_iter().collect::<Result<Vec<ReturnSuccess>, _>>();
let result_table = match result {
Ok(t) => t,
Err(e) => return OutputStream::one(Err(e)),
};
let table = result_table
.into_iter()
.filter_map(|x| x.raw_value())
.collect();
OutputStream::one(Ok(ReturnSuccess::Value(UntaggedValue::Table(table).into())))
// If it returned just one value, just take that value
if vec.len() == 1 {
return OutputStream::one(
vec.into_iter()
.next()
.expect("This should be impossible, we just checked that vec.len() == 1."),
);
}
Err(e) => OutputStream::one(Err(e)),
// If it returned multiple values, we need to put them into a table and
// return that.
let result = vec.into_iter().collect::<Result<Vec<ReturnSuccess>, _>>();
let result_table = match result {
Ok(t) => t,
Err(e) => return OutputStream::one(Err(e)),
};
let table = result_table
.into_iter()
.filter_map(|x| x.raw_value())
.collect();
OutputStream::one(Ok(ReturnSuccess::Value(UntaggedValue::Table(table).into())))
}
Err(e) => OutputStream::one(Err(e)),
}
}

View File

@ -16,7 +16,6 @@ pub struct EachWindowArgs {
stride: Option<Tagged<usize>>,
}
#[async_trait]
impl WholeStreamCommand for EachWindow {
fn name(&self) -> &str {
"each window"
@ -50,16 +49,15 @@ impl WholeStreamCommand for EachWindow {
}]
}
async fn run(&self, raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let context = Arc::new(EvaluationContext::from_args(&raw_args));
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process().await?;
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process()?;
let block = Arc::new(Box::new(each_args.block));
let mut window: Vec<_> = input
.by_ref()
.take(*each_args.window_size - 1)
.collect::<Vec<_>>()
.await;
.collect::<Vec<_>>();
// `window` must start with dummy values, which will be removed on the first iteration
let stride = each_args.stride.map(|x| *x).unwrap_or(1);
@ -67,7 +65,7 @@ impl WholeStreamCommand for EachWindow {
Ok(input
.enumerate()
.then(move |(i, input)| {
.map(move |(i, input)| {
// This would probably be more efficient if `last` was a VecDeque
// But we can't have that because it needs to be put into a Table
window.remove(0);
@ -77,15 +75,13 @@ impl WholeStreamCommand for EachWindow {
let context = context.clone();
let local_window = window.clone();
async move {
if i % stride == 0 {
Some(run_block_on_vec(local_window, block, context).await)
} else {
None
}
if i % stride == 0 {
Some(run_block_on_vec(local_window, block, context))
} else {
None
}
})
.filter_map(|x| async { x })
.filter_map(|x| x)
.flatten()
.to_output_stream())
}

View File

@ -13,7 +13,6 @@ pub struct EchoArgs {
pub rest: Vec<Value>,
}
#[async_trait]
impl WholeStreamCommand for Echo {
fn name(&self) -> &str {
"echo"
@ -27,8 +26,8 @@ impl WholeStreamCommand for Echo {
"Echo the arguments back to the user."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
echo(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
echo(args)
}
fn examples(&self) -> Vec<Example> {
@ -47,8 +46,8 @@ impl WholeStreamCommand for Echo {
}
}
async fn echo(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (args, _): (EchoArgs, _) = args.process().await?;
fn echo(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (args, _): (EchoArgs, _) = args.process()?;
let stream = args.rest.into_iter().map(|i| match i.as_string() {
Ok(s) => OutputStream::one(Ok(ReturnSuccess::Value(
@ -58,17 +57,19 @@ async fn echo(args: CommandArgs) -> Result<OutputStream, ShellError> {
Value {
value: UntaggedValue::Table(table),
..
} => futures::stream::iter(table.into_iter().map(ReturnSuccess::value))
} => table
.into_iter()
.map(ReturnSuccess::value)
.to_output_stream(),
Value {
value: UntaggedValue::Primitive(Primitive::Range(range)),
tag,
} => futures::stream::iter(RangeIterator::new(*range, tag)).to_output_stream(),
} => RangeIterator::new(*range, tag).to_output_stream(),
x => OutputStream::one(Ok(ReturnSuccess::Value(x))),
},
});
Ok(futures::stream::iter(stream).flatten().to_output_stream())
Ok(stream.flatten().to_output_stream())
}
struct RangeIterator {

View File

@ -8,7 +8,6 @@ use nu_protocol::{
};
use crate::utils::arguments::arguments;
use futures::stream::once;
use nu_value_ext::{as_string, ValueExt};
#[derive(Deserialize)]
@ -18,7 +17,6 @@ pub struct Arguments {
pub struct Command;
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"empty?"
@ -35,8 +33,8 @@ impl WholeStreamCommand for Command {
"Check for empty values."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
is_empty(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
is_empty(args)
}
fn examples(&self) -> Vec<Example> {
@ -81,32 +79,28 @@ impl WholeStreamCommand for Command {
}
}
async fn is_empty(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn is_empty(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let name_tag = Arc::new(args.call_info.name_tag.clone());
let context = Arc::new(EvaluationContext::from_args(&args));
let (Arguments { mut rest }, input) = args.process().await?;
let (Arguments { mut rest }, input) = args.process()?;
let (columns, default_block): (Vec<ColumnPath>, Option<Box<CapturedBlock>>) =
arguments(&mut rest)?;
let default_block = Arc::new(default_block);
if input.is_empty() {
let stream = futures::stream::iter(vec![
UntaggedValue::Primitive(Primitive::Nothing).into_value(tag)
]);
let stream = vec![UntaggedValue::Primitive(Primitive::Nothing).into_value(tag)].into_iter();
return Ok(InputStream::from_stream(stream)
.then(move |input| {
.map(move |input| {
let tag = name_tag.clone();
let context = context.clone();
let block = default_block.clone();
let columns = vec![];
async {
match process_row(context, input, block, columns, tag).await {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
match process_row(context, input, block, columns, tag) {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
})
.flatten()
@ -114,24 +108,22 @@ async fn is_empty(args: CommandArgs) -> Result<OutputStream, ShellError> {
}
Ok(input
.then(move |input| {
.map(move |input| {
let tag = name_tag.clone();
let context = context.clone();
let block = default_block.clone();
let columns = columns.clone();
async {
match process_row(context, input, block, columns, tag).await {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
match process_row(context, input, block, columns, tag) {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
})
.flatten()
.to_output_stream())
}
async fn process_row(
fn process_row(
context: Arc<EvaluationContext>,
input: Value,
default_block: Arc<Option<Box<CapturedBlock>>>,
@ -144,18 +136,18 @@ async fn process_row(
if let Some(default_block) = &*default_block {
let for_block = input.clone();
let input_stream = once(async { Ok(for_block) }).to_input_stream();
let input_stream = vec![Ok(for_block)].into_iter().to_input_stream();
context.scope.enter_scope();
context.scope.add_vars(&default_block.captured.entries);
context.scope.add_var("$it", input.clone());
let stream = run_block(&default_block.block, &*context, input_stream).await;
let stream = run_block(&default_block.block, &*context, input_stream);
context.scope.exit_scope();
let mut stream = stream?;
*results = Some({
let values = stream.drain_vec().await;
let values = stream.drain_vec();
let errors = context.get_errors();

View File

@ -17,7 +17,6 @@ pub struct EnterArgs {
encoding: Option<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for Enter {
fn name(&self) -> &str {
"enter"
@ -51,8 +50,8 @@ For a more complete list of encodings please refer to the encoding_rs
documentation link at https://docs.rs/encoding_rs/0.8.28/encoding_rs/#statics"#
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
enter(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
enter(args)
}
fn examples(&self) -> Vec<Example> {
@ -76,7 +75,7 @@ documentation link at https://docs.rs/encoding_rs/0.8.28/encoding_rs/#statics"#
}
}
async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let scope = raw_args.scope.clone();
let shell_manager = raw_args.shell_manager.clone();
let head = raw_args.call_info.args.head.clone();
@ -85,13 +84,12 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let current_errors = raw_args.current_errors.clone();
let host = raw_args.host.clone();
let tag = raw_args.call_info.name_tag.clone();
let (EnterArgs { location, encoding }, _) = raw_args.process().await?;
let (EnterArgs { location, encoding }, _) = raw_args.process()?;
let location_string = location.display().to_string();
let location_clone = location_string.clone();
if location.is_dir() {
Ok(OutputStream::one(ReturnSuccess::action(
CommandAction::EnterShell(location_clone),
CommandAction::EnterShell(location_string),
)))
} else {
// If it's a file, attempt to open the file as a value and enter it
@ -102,11 +100,10 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let (file_extension, tagged_contents) = crate::commands::open::fetch(
&full_path,
&PathBuf::from(location_clone),
&PathBuf::from(location_string),
span,
encoding,
)
.await?;
)?;
match tagged_contents.value {
UntaggedValue::Primitive(Primitive::String(_)) => {
@ -127,18 +124,17 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
span: Span::unknown(),
external_redirection: ExternalRedirection::Stdout,
},
name_tag: tag.clone(),
name_tag: tag,
},
scope: scope.clone(),
scope,
};
let tag = tagged_contents.tag.clone();
let mut result = converter
.run(new_args.with_input(vec![tagged_contents]))
.await?;
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
result.drain_vec().await;
Ok(futures::stream::iter(result_vec.into_iter().map(
move |res| match res {
let mut result =
converter.run(new_args.with_input(vec![tagged_contents]))?;
let result_vec: Vec<Result<ReturnSuccess, ShellError>> = result.drain_vec();
Ok(result_vec
.into_iter()
.map(move |res| match res {
Ok(ReturnSuccess::Value(Value { value, .. })) => Ok(
ReturnSuccess::Action(CommandAction::EnterValueShell(Value {
value,
@ -146,9 +142,8 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
})),
),
x => x,
},
))
.to_output_stream())
})
.to_output_stream())
} else {
Ok(OutputStream::one(ReturnSuccess::action(
CommandAction::EnterValueShell(tagged_contents),

View File

@ -12,7 +12,6 @@ pub struct EveryArgs {
skip: Tagged<bool>,
}
#[async_trait]
impl WholeStreamCommand for Every {
fn name(&self) -> &str {
"every"
@ -36,8 +35,8 @@ impl WholeStreamCommand for Every {
"Show (or skip) every n-th row, starting from the first one."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
every(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
every(args)
}
fn examples(&self) -> Vec<Example> {
@ -63,15 +62,15 @@ impl WholeStreamCommand for Every {
}
}
async fn every(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (EveryArgs { stride, skip }, input) = args.process().await?;
fn every(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (EveryArgs { stride, skip }, input) = args.process()?;
let stride = stride.item;
let skip = skip.item;
Ok(input
.enumerate()
.filter_map(move |(i, value)| async move {
.filter_map(move |(i, value)| {
let stride_desired = if stride < 1 { 1 } else { stride } as usize;
let should_include = skip == (i % stride_desired != 0);

View File

@ -13,7 +13,6 @@ pub struct ExecArgs {
pub rest: Vec<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for Exec {
fn name(&self) -> &str {
"exec"
@ -32,8 +31,8 @@ impl WholeStreamCommand for Exec {
"Execute command."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
exec(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
exec(args)
}
fn examples(&self) -> Vec<Example> {
@ -53,12 +52,12 @@ impl WholeStreamCommand for Exec {
}
#[cfg(unix)]
async fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
use std::os::unix::process::CommandExt;
use std::process::Command;
let name = args.call_info.name_tag.clone();
let (args, _): (ExecArgs, _) = args.process().await?;
let (args, _): (ExecArgs, _) = args.process()?;
let mut command = Command::new(args.command.item);
for tagged_arg in args.rest {
@ -75,7 +74,7 @@ async fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
}
#[cfg(not(unix))]
async fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn exec(args: CommandArgs) -> Result<OutputStream, ShellError> {
Err(ShellError::labeled_error(
"Error on exec",
"exec is not supported on your platform",

View File

@ -4,7 +4,6 @@ use nu_protocol::{CommandAction, ReturnSuccess, Signature, SyntaxShape};
pub struct Exit;
#[async_trait]
impl WholeStreamCommand for Exit {
fn name(&self) -> &str {
"exit"
@ -24,8 +23,8 @@ impl WholeStreamCommand for Exit {
"Exit the current shell (or all shells)."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
exit(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
exit(args)
}
fn examples(&self) -> Vec<Example> {
@ -44,8 +43,8 @@ impl WholeStreamCommand for Exit {
}
}
pub async fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
pub fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let code = if let Some(value) = args.call_info.args.nth(0) {
value.as_i32()?

View File

@ -11,7 +11,6 @@ pub struct FirstArgs {
rows: Option<Tagged<usize>>,
}
#[async_trait]
impl WholeStreamCommand for First {
fn name(&self) -> &str {
"first"
@ -29,8 +28,8 @@ impl WholeStreamCommand for First {
"Show only the first number of rows."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
first(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
first(args)
}
fn examples(&self) -> Vec<Example> {
@ -52,8 +51,8 @@ impl WholeStreamCommand for First {
}
}
async fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (FirstArgs { rows }, input) = args.process().await?;
fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (FirstArgs { rows }, input) = args.process()?;
let rows_desired = if let Some(quantity) = rows {
*quantity
} else {

View File

@ -13,7 +13,6 @@ pub struct Arguments {
rest: Vec<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"flatten"
@ -27,8 +26,8 @@ impl WholeStreamCommand for Command {
"Flatten the table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
flatten(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
flatten(args)
}
fn examples(&self) -> Vec<Example> {
@ -52,12 +51,12 @@ impl WholeStreamCommand for Command {
}
}
async fn flatten(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn flatten(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (Arguments { rest: columns }, input) = args.process().await?;
let (Arguments { rest: columns }, input) = args.process()?;
Ok(input
.map(move |item| futures::stream::iter(flat_value(&columns, &item, &tag).into_iter()))
.map(move |item| flat_value(&columns, &item, &tag).into_iter())
.flatten()
.to_output_stream())
}

View File

@ -13,7 +13,6 @@ pub struct FormatArgs {
pattern: Tagged<String>,
}
#[async_trait]
impl WholeStreamCommand for Format {
fn name(&self) -> &str {
"format"
@ -31,8 +30,8 @@ impl WholeStreamCommand for Format {
"Format columns into a string using a simple pattern."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
format_command(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
format_command(args)
}
fn examples(&self) -> Vec<Example> {
@ -44,49 +43,46 @@ impl WholeStreamCommand for Format {
}
}
async fn format_command(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn format_command(args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let (FormatArgs { pattern }, input) = args.process().await?;
let (FormatArgs { pattern }, input) = args.process()?;
let format_pattern = format(&pattern);
let commands = Arc::new(format_pattern);
Ok(input
.then(move |value| {
.map(move |value| {
let mut output = String::new();
let commands = commands.clone();
let ctx = ctx.clone();
async move {
for command in &*commands {
match command {
FormatCommand::Text(s) => {
output.push_str(&s);
}
FormatCommand::Column(c) => {
// FIXME: use the correct spans
let full_column_path = nu_parser::parse_full_column_path(
&(c.to_string()).spanned(Span::unknown()),
&ctx.scope,
);
for command in &*commands {
match command {
FormatCommand::Text(s) => {
output.push_str(&s);
}
FormatCommand::Column(c) => {
// FIXME: use the correct spans
let full_column_path = nu_parser::parse_full_column_path(
&(c.to_string()).spanned(Span::unknown()),
&ctx.scope,
);
ctx.scope.enter_scope();
ctx.scope.add_var("$it", value.clone());
let result = evaluate_baseline_expr(&full_column_path.0, &*ctx).await;
ctx.scope.exit_scope();
ctx.scope.enter_scope();
ctx.scope.add_var("$it", value.clone());
let result = evaluate_baseline_expr(&full_column_path.0, &*ctx);
ctx.scope.exit_scope();
if let Ok(c) = result {
output
.push_str(&value::format_leaf(c.borrow()).plain_string(100_000))
} else {
// That column doesn't match, so don't emit anything
}
if let Ok(c) = result {
output.push_str(&value::format_leaf(c.borrow()).plain_string(100_000))
} else {
// That column doesn't match, so don't emit anything
}
}
}
ReturnSuccess::value(UntaggedValue::string(output).into_untagged_value())
}
ReturnSuccess::value(UntaggedValue::string(output).into_untagged_value())
})
.to_output_stream())
}

View File

@ -16,7 +16,6 @@ pub struct Arguments {
format: Tagged<String>,
}
#[async_trait]
impl WholeStreamCommand for FileSize {
fn name(&self) -> &str {
"format filesize"
@ -40,8 +39,8 @@ impl WholeStreamCommand for FileSize {
"Converts a column of filesizes to some specified format"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
filesize(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
filesize(args)
}
fn examples(&self) -> Vec<Example> {
@ -60,7 +59,7 @@ impl WholeStreamCommand for FileSize {
}
}
async fn process_row(
fn process_row(
input: Value,
format: Tagged<String>,
field: Arc<ColumnPath>,
@ -92,20 +91,18 @@ async fn process_row(
})
}
async fn filesize(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { field, format }, input) = raw_args.process().await?;
fn filesize(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { field, format }, input) = raw_args.process()?;
let field = Arc::new(field);
Ok(input
.then(move |input| {
.map(move |input| {
let format = format.clone();
let field = field.clone();
async {
match process_row(input, format, field).await {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
match process_row(input, format, field) {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
})
.flatten()

View File

@ -5,7 +5,6 @@ use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
pub struct From;
#[async_trait]
impl WholeStreamCommand for From {
fn name(&self) -> &str {
"from"
@ -19,7 +18,7 @@ impl WholeStreamCommand for From {
"Parse content (string or binary) as a table (input format based on subcommand, like csv, ini, json, toml)."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(get_full_help(&From, &args.scope)).into_value(Tag::unknown()),
)))

View File

@ -12,7 +12,6 @@ pub struct FromCsvArgs {
separator: Option<Value>,
}
#[async_trait]
impl WholeStreamCommand for FromCsv {
fn name(&self) -> &str {
"from csv"
@ -37,8 +36,8 @@ impl WholeStreamCommand for FromCsv {
"Parse text as .csv and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_csv(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_csv(args)
}
fn examples(&self) -> Vec<Example> {
@ -67,7 +66,7 @@ impl WholeStreamCommand for FromCsv {
}
}
async fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let (
@ -76,7 +75,7 @@ async fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
separator,
},
input,
) = args.process().await?;
) = args.process()?;
let sep = match separator {
Some(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
@ -100,7 +99,7 @@ async fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
_ => ',',
};
from_delimited_data(noheaders, sep, "CSV", input, name).await
from_delimited_data(noheaders, sep, "CSV", input, name)
}
#[cfg(test)]

View File

@ -45,7 +45,7 @@ fn from_delimited_string_to_value(
Ok(UntaggedValue::Table(rows).into_value(&tag))
}
pub async fn from_delimited_data(
pub fn from_delimited_data(
noheaders: bool,
sep: char,
format_name: &'static str,
@ -53,7 +53,7 @@ pub async fn from_delimited_data(
name: Tag,
) -> Result<OutputStream, ShellError> {
let name_tag = name;
let concat_string = input.collect_string(name_tag.clone()).await?;
let concat_string = input.collect_string(name_tag.clone())?;
let sample_lines = concat_string.item.lines().take(3).collect_vec().join("\n");
match from_delimited_string_to_value(concat_string.item, noheaders, sep, name_tag.clone()) {
@ -61,7 +61,7 @@ pub async fn from_delimited_data(
Value {
value: UntaggedValue::Table(list),
..
} => Ok(futures::stream::iter(list).to_output_stream()),
} => Ok(list.into_iter().to_output_stream()),
x => Ok(OutputStream::one(x)),
},
Err(err) => {
@ -80,7 +80,7 @@ pub async fn from_delimited_data(
Err(ShellError::labeled_error_with_secondary(
line_one,
line_two,
name_tag.clone(),
name_tag,
"value originates from here",
concat_string.tag,
))

View File

@ -16,7 +16,6 @@ pub struct FromEmlArgs {
preview_body: Option<Tagged<usize>>,
}
#[async_trait]
impl WholeStreamCommand for FromEml {
fn name(&self) -> &str {
"from eml"
@ -35,8 +34,8 @@ impl WholeStreamCommand for FromEml {
"Parse text as .eml and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_eml(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_eml(args)
}
}
@ -73,10 +72,10 @@ fn headerfieldvalue_to_value(tag: &Tag, value: &HeaderFieldValue) -> UntaggedVal
}
}
async fn from_eml(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_eml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (eml_args, input): (FromEmlArgs, _) = args.process().await?;
let value = input.collect_string(tag.clone()).await?;
let (eml_args, input): (FromEmlArgs, _) = args.process()?;
let value = input.collect_string(tag.clone())?;
let body_preview = eml_args
.preview_body

View File

@ -9,7 +9,6 @@ use std::io::BufReader;
pub struct FromIcs;
#[async_trait]
impl WholeStreamCommand for FromIcs {
fn name(&self) -> &str {
"from ics"
@ -23,17 +22,17 @@ impl WholeStreamCommand for FromIcs {
"Parse text as .ics and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ics(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ics(args)
}
}
async fn from_ics(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn from_ics(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let input_string = input.collect_string(tag.clone()).await?.item;
let input_string = input.collect_string(tag.clone())?.item;
let input_bytes = input_string.as_bytes();
let buf_reader = BufReader::new(input_bytes);
let parser = ical::IcalParser::new(buf_reader);
@ -53,7 +52,7 @@ async fn from_ics(args: CommandArgs) -> Result<OutputStream, ShellError> {
}
}
Ok(futures::stream::iter(output).to_output_stream())
Ok(output.into_iter().to_output_stream())
}
fn calendar_to_value(calendar: IcalCalendar, tag: Tag) -> Value {

View File

@ -6,7 +6,6 @@ use std::collections::HashMap;
pub struct FromIni;
#[async_trait]
impl WholeStreamCommand for FromIni {
fn name(&self) -> &str {
"from ini"
@ -20,8 +19,8 @@ impl WholeStreamCommand for FromIni {
"Parse text as .ini and create table"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ini(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ini(args)
}
}
@ -60,18 +59,18 @@ pub fn from_ini_string_to_value(
Ok(convert_ini_top_to_nu_value(&v, tag))
}
async fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let concat_string = input.collect_string(tag.clone()).await?;
let concat_string = input.collect_string(tag.clone())?;
match from_ini_string_to_value(concat_string.item, tag.clone()) {
Ok(x) => match x {
Value {
value: UntaggedValue::Table(list),
..
} => Ok(futures::stream::iter(list).to_output_stream()),
} => Ok(list.into_iter().to_output_stream()),
x => Ok(OutputStream::one(x)),
},
Err(_) => Err(ShellError::labeled_error_with_secondary(

View File

@ -10,7 +10,6 @@ pub struct FromJsonArgs {
objects: bool,
}
#[async_trait]
impl WholeStreamCommand for FromJson {
fn name(&self) -> &str {
"from json"
@ -28,8 +27,8 @@ impl WholeStreamCommand for FromJson {
"Parse text as .json and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_json(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_json(args)
}
}
@ -68,17 +67,18 @@ pub fn from_json_string_to_value(s: String, tag: impl Into<Tag>) -> nu_json::Res
Ok(convert_json_value_to_nu_value(&v, tag))
}
async fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_tag = args.call_info.name_tag.clone();
let (FromJsonArgs { objects }, input) = args.process().await?;
let concat_string = input.collect_string(name_tag.clone()).await?;
let (FromJsonArgs { objects }, input) = args.process()?;
let concat_string = input.collect_string(name_tag.clone())?;
let string_clone: Vec<_> = concat_string.item.lines().map(|x| x.to_string()).collect();
if objects {
Ok(
futures::stream::iter(string_clone.into_iter().filter_map(move |json_str| {
Ok(string_clone
.into_iter()
.filter_map(move |json_str| {
if json_str.is_empty() {
return None;
}
@ -99,19 +99,19 @@ async fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
)))
}
}
}))
.to_output_stream(),
)
})
.to_output_stream())
} else {
match from_json_string_to_value(concat_string.item, name_tag.clone()) {
Ok(x) => match x {
Value {
value: UntaggedValue::Table(list),
..
} => Ok(
futures::stream::iter(list.into_iter().map(ReturnSuccess::value))
.to_output_stream(),
),
} => Ok(list
.into_iter()
.map(ReturnSuccess::value)
.to_output_stream()),
x => Ok(OutputStream::one(ReturnSuccess::value(x))),
},
Err(e) => {

View File

@ -13,7 +13,6 @@ pub struct FromOdsArgs {
noheaders: bool,
}
#[async_trait]
impl WholeStreamCommand for FromOds {
fn name(&self) -> &str {
"from ods"
@ -31,12 +30,12 @@ impl WholeStreamCommand for FromOds {
"Parse OpenDocument Spreadsheet(.ods) data and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ods(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ods(args)
}
}
async fn from_ods(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_ods(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let span = tag.span;
@ -45,8 +44,8 @@ async fn from_ods(args: CommandArgs) -> Result<OutputStream, ShellError> {
noheaders: _noheaders,
},
input,
) = args.process().await?;
let bytes = input.collect_binary(tag.clone()).await?;
) = args.process()?;
let bytes = input.collect_binary(tag.clone())?;
let buf: Cursor<Vec<u8>> = Cursor::new(bytes.item);
let mut ods = Ods::<_>::new(buf).map_err(|_| {
ShellError::labeled_error("Could not load ods file", "could not load ods file", &tag)

View File

@ -20,7 +20,6 @@ pub struct FromSsvArgs {
const STRING_REPRESENTATION: &str = "from ssv";
const DEFAULT_MINIMUM_SPACES: usize = 2;
#[async_trait]
impl WholeStreamCommand for FromSsv {
fn name(&self) -> &str {
STRING_REPRESENTATION
@ -46,8 +45,8 @@ impl WholeStreamCommand for FromSsv {
"Parse text as space-separated values and create a table. The default minimum number of spaces counted as a separator is 2."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ssv(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_ssv(args)
}
}
@ -247,7 +246,7 @@ fn from_ssv_string_to_value(
UntaggedValue::Table(rows).into_value(&tag)
}
async fn from_ssv(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_ssv(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let (
FromSsvArgs {
@ -256,8 +255,8 @@ async fn from_ssv(args: CommandArgs) -> Result<OutputStream, ShellError> {
minimum_spaces,
},
input,
) = args.process().await?;
let concat_string = input.collect_string(name.clone()).await?;
) = args.process()?;
let concat_string = input.collect_string(name.clone())?;
let split_at = match minimum_spaces {
Some(number) => number.item,
None => DEFAULT_MINIMUM_SPACES,
@ -269,14 +268,15 @@ async fn from_ssv(args: CommandArgs) -> Result<OutputStream, ShellError> {
noheaders,
aligned_columns,
split_at,
name.clone(),
name,
) {
Value {
value: UntaggedValue::Table(list),
..
} => {
futures::stream::iter(list.into_iter().map(ReturnSuccess::value)).to_output_stream()
}
} => list
.into_iter()
.map(ReturnSuccess::value)
.to_output_stream(),
x => OutputStream::one(ReturnSuccess::value(x)),
},
)

View File

@ -5,7 +5,6 @@ use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, Untagg
pub struct FromToml;
#[async_trait]
impl WholeStreamCommand for FromToml {
fn name(&self) -> &str {
"from toml"
@ -19,8 +18,8 @@ impl WholeStreamCommand for FromToml {
"Parse text as .toml and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_toml(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_toml(args)
}
}
@ -61,19 +60,21 @@ pub fn from_toml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value
Ok(convert_toml_value_to_nu_value(&v, tag))
}
pub async fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
pub fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let concat_string = input.collect_string(tag.clone()).await?;
let concat_string = input.collect_string(tag.clone())?;
Ok(
match from_toml_string_to_value(concat_string.item, tag.clone()) {
Ok(x) => match x {
Value {
value: UntaggedValue::Table(list),
..
} => futures::stream::iter(list.into_iter().map(ReturnSuccess::value))
} => list
.into_iter()
.map(ReturnSuccess::value)
.to_output_stream(),
x => OutputStream::one(ReturnSuccess::value(x)),
},

View File

@ -11,7 +11,6 @@ pub struct FromTsvArgs {
noheaders: bool,
}
#[async_trait]
impl WholeStreamCommand for FromTsv {
fn name(&self) -> &str {
"from tsv"
@ -29,16 +28,16 @@ impl WholeStreamCommand for FromTsv {
"Parse text as .tsv and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_tsv(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_tsv(args)
}
}
async fn from_tsv(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_tsv(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let (FromTsvArgs { noheaders }, input) = args.process().await?;
let (FromTsvArgs { noheaders }, input) = args.process()?;
from_delimited_data(noheaders, '\t', "TSV", input, name).await
from_delimited_data(noheaders, '\t', "TSV", input, name)
}
#[cfg(test)]

View File

@ -5,7 +5,6 @@ use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue};
pub struct FromUrl;
#[async_trait]
impl WholeStreamCommand for FromUrl {
fn name(&self) -> &str {
"from url"
@ -19,17 +18,17 @@ impl WholeStreamCommand for FromUrl {
"Parse url-encoded string as a table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_url(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_url(args)
}
}
async fn from_url(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn from_url(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let concat_string = input.collect_string(tag.clone()).await?;
let concat_string = input.collect_string(tag.clone())?;
let result = serde_urlencoded::from_str::<Vec<(String, String)>>(&concat_string.item);

View File

@ -8,7 +8,6 @@ use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, Untagg
pub struct FromVcf;
#[async_trait]
impl WholeStreamCommand for FromVcf {
fn name(&self) -> &str {
"from vcf"
@ -22,17 +21,17 @@ impl WholeStreamCommand for FromVcf {
"Parse text as .vcf and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_vcf(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_vcf(args)
}
}
async fn from_vcf(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn from_vcf(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let input_string = input.collect_string(tag.clone()).await?.item;
let input_string = input.collect_string(tag.clone())?.item;
let input_bytes = input_string.into_bytes();
let cursor = std::io::Cursor::new(input_bytes);
let parser = ical::VcardParser::new(cursor);
@ -46,7 +45,9 @@ async fn from_vcf(args: CommandArgs) -> Result<OutputStream, ShellError> {
)),
});
Ok(futures::stream::iter(iter).to_output_stream())
let collected: Vec<_> = iter.collect();
Ok(collected.into_iter().to_output_stream())
}
fn contact_to_value(contact: VcardContact, tag: Tag) -> Value {

View File

@ -13,7 +13,6 @@ pub struct FromXlsxArgs {
noheaders: bool,
}
#[async_trait]
impl WholeStreamCommand for FromXlsx {
fn name(&self) -> &str {
"from xlsx"
@ -31,12 +30,12 @@ impl WholeStreamCommand for FromXlsx {
"Parse binary Excel(.xlsx) data and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_xlsx(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_xlsx(args)
}
}
async fn from_xlsx(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn from_xlsx(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let span = tag.span;
let (
@ -44,8 +43,8 @@ async fn from_xlsx(args: CommandArgs) -> Result<OutputStream, ShellError> {
noheaders: _noheaders,
},
input,
) = args.process().await?;
let value = input.collect_binary(tag.clone()).await?;
) = args.process()?;
let value = input.collect_binary(tag.clone())?;
let buf: Cursor<Vec<u8>> = Cursor::new(value.item);
let mut xls = Xlsx::<_>::new(buf).map_err(|_| {

View File

@ -5,7 +5,6 @@ use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, Untagg
pub struct FromXml;
#[async_trait]
impl WholeStreamCommand for FromXml {
fn name(&self) -> &str {
"from xml"
@ -19,8 +18,8 @@ impl WholeStreamCommand for FromXml {
"Parse text as .xml and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_xml(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_xml(args)
}
}
@ -95,12 +94,12 @@ pub fn from_xml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value,
Ok(from_document_to_value(&parsed, tag))
}
async fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let concat_string = input.collect_string(tag.clone()).await?;
let concat_string = input.collect_string(tag.clone())?;
Ok(
match from_xml_string_to_value(concat_string.item, tag.clone()) {
@ -108,7 +107,9 @@ async fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
Value {
value: UntaggedValue::Table(list),
..
} => futures::stream::iter(list.into_iter().map(ReturnSuccess::value))
} => list
.into_iter()
.map(ReturnSuccess::value)
.to_output_stream(),
x => OutputStream::one(ReturnSuccess::value(x)),
},

View File

@ -5,7 +5,6 @@ use nu_protocol::{Primitive, Signature, TaggedDictBuilder, UntaggedValue, Value}
pub struct FromYaml;
#[async_trait]
impl WholeStreamCommand for FromYaml {
fn name(&self) -> &str {
"from yaml"
@ -19,14 +18,13 @@ impl WholeStreamCommand for FromYaml {
"Parse text as .yaml/.yml and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_yaml(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_yaml(args)
}
}
pub struct FromYml;
#[async_trait]
impl WholeStreamCommand for FromYml {
fn name(&self) -> &str {
"from yml"
@ -40,8 +38,8 @@ impl WholeStreamCommand for FromYml {
"Parse text as .yaml/.yml and create table."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_yaml(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
from_yaml(args)
}
}
@ -133,19 +131,19 @@ pub fn from_yaml_string_to_value(s: String, tag: impl Into<Tag>) -> Result<Value
convert_yaml_value_to_nu_value(&v, tag)
}
async fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once().await?;
fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once()?;
let tag = args.name_tag();
let input = args.input;
let concat_string = input.collect_string(tag.clone()).await?;
let concat_string = input.collect_string(tag.clone())?;
match from_yaml_string_to_value(concat_string.item, tag.clone()) {
Ok(x) => match x {
Value {
value: UntaggedValue::Table(list),
..
} => Ok(futures::stream::iter(list).to_output_stream()),
} => Ok(list.into_iter().to_output_stream()),
x => Ok(OutputStream::one(x)),
},
Err(_) => Err(ShellError::labeled_error_with_secondary(

View File

@ -18,7 +18,6 @@ pub struct Arguments {
rest: Vec<Value>,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"get"
@ -35,8 +34,8 @@ impl WholeStreamCommand for Command {
"Open given cells as text."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
get(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
get(args)
}
fn examples(&self) -> Vec<Example> {
@ -55,26 +54,28 @@ impl WholeStreamCommand for Command {
}
}
pub async fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { mut rest }, mut input) = args.process().await?;
pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { mut rest }, mut input) = args.process()?;
let (column_paths, _) = arguments(&mut rest)?;
if column_paths.is_empty() {
let vec = input.drain_vec().await;
let vec = input.drain_vec();
let descs = nu_protocol::merge_descriptors(&vec);
Ok(futures::stream::iter(descs.into_iter().map(ReturnSuccess::value)).to_output_stream())
Ok(descs
.into_iter()
.map(ReturnSuccess::value)
.to_output_stream())
} else {
trace!("get {:?}", column_paths);
let output_stream = input
.map(move |item| {
let output = column_paths
column_paths
.iter()
.map(move |path| get_output(&item, path))
.flatten()
.collect::<Vec<_>>();
futures::stream::iter(output)
.collect::<Vec<_>>()
})
.flatten()
.to_output_stream();

View File

@ -13,7 +13,6 @@ pub struct Arguments {
grouper: Option<Value>,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"group-by"
@ -31,8 +30,8 @@ impl WholeStreamCommand for Command {
"Create a new table grouped."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
group_by(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
group_by(args)
}
#[allow(clippy::unwrap_used)]
@ -128,12 +127,12 @@ enum Grouper {
ByBlock,
}
pub async fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let context = Arc::new(EvaluationContext::from_args(&args));
let (Arguments { grouper }, input) = args.process().await?;
let (Arguments { grouper }, input) = args.process()?;
let values: Vec<Value> = input.collect().await;
let values: Vec<Value> = input.collect();
let mut keys: Vec<Result<String, ShellError>> = vec![];
let mut group_strategy = Grouper::ByColumn(None);
@ -149,10 +148,9 @@ pub async fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
let run = block.clone();
let context = context.clone();
match crate::commands::each::process_row(run, context, value.clone()).await {
match crate::commands::each::process_row(run, context, value.clone()) {
Ok(mut s) => {
let collection: Vec<Result<ReturnSuccess, ShellError>> =
s.drain_vec().await;
let collection: Vec<Result<ReturnSuccess, ShellError>> = s.drain_vec();
if collection.len() > 1 {
return Err(ShellError::labeled_error(
@ -209,7 +207,7 @@ pub async fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
let group_value = match group_strategy {
Grouper::ByBlock => {
let map = keys.clone();
let map = keys;
let block = Box::new(move |idx: usize, row: &Value| match map.get(idx) {
Some(Ok(key)) => Ok(key.clone()),

View File

@ -13,7 +13,6 @@ pub struct GroupByDateArgs {
format: Option<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for GroupByDate {
fn name(&self) -> &str {
"group-by date"
@ -38,8 +37,8 @@ impl WholeStreamCommand for GroupByDate {
"creates a table grouped by date."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
group_by_date(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
group_by_date(args)
}
fn examples(&self) -> Vec<Example> {
@ -59,7 +58,7 @@ enum GroupByColumn {
Name(Option<Tagged<String>>),
}
pub async fn group_by_date(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn group_by_date(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let (
GroupByDateArgs {
@ -67,8 +66,8 @@ pub async fn group_by_date(args: CommandArgs) -> Result<OutputStream, ShellError
format,
},
input,
) = args.process().await?;
let values: Vec<Value> = input.collect().await;
) = args.process()?;
let values: Vec<Value> = input.collect();
if values.is_empty() {
Err(ShellError::labeled_error(

View File

@ -30,7 +30,6 @@ pub enum ActionType {
}
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"hash base64"
@ -65,8 +64,8 @@ impl WholeStreamCommand for SubCommand {
"base64 encode or decode a value"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
operate(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
operate(args)
}
fn examples(&self) -> Vec<Example> {
@ -96,8 +95,8 @@ impl WholeStreamCommand for SubCommand {
}
}
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_tag = &args.call_info.name_tag.clone();
fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_tag = args.call_info.name_tag.clone();
let (
Arguments {
@ -107,7 +106,7 @@ async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
rest,
},
input,
) = args.process().await?;
) = args.process()?;
if encode.item && decode.item {
return Ok(OutputStream::one(Err(ShellError::labeled_error(

View File

@ -5,7 +5,6 @@ use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
pub struct Command;
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"hash"
@ -22,7 +21,7 @@ impl WholeStreamCommand for Command {
"Apply hash function."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
)))

View File

@ -14,7 +14,6 @@ pub struct Arguments {
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"hash md5"
@ -31,8 +30,8 @@ impl WholeStreamCommand for SubCommand {
"md5 encode a value"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
operate(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
operate(args)
}
fn examples(&self) -> Vec<Example> {
@ -57,8 +56,8 @@ impl WholeStreamCommand for SubCommand {
}
}
async fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rest }, input) = args.process().await?;
fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rest }, input) = args.process()?;
let column_paths: Vec<_> = rest;

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use futures::stream::StreamExt;
use indexmap::IndexMap;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
@ -8,7 +8,6 @@ use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
pub struct Headers;
#[async_trait]
impl WholeStreamCommand for Headers {
fn name(&self) -> &str {
"headers"
@ -22,8 +21,8 @@ impl WholeStreamCommand for Headers {
"Use the first row of the table as column names."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
headers(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
headers(args)
}
fn examples(&self) -> Vec<Example> {
@ -42,9 +41,9 @@ impl WholeStreamCommand for Headers {
}
}
pub async fn headers(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn headers(args: CommandArgs) -> Result<OutputStream, ShellError> {
let input = args.input;
let rows: Vec<Value> = input.collect().await;
let rows: Vec<Value> = input.collect();
if rows.is_empty() {
return Err(ShellError::untagged_runtime_error(
@ -77,8 +76,10 @@ pub async fn headers(args: CommandArgs) -> Result<OutputStream, ShellError> {
)),
}?;
Ok(
futures::stream::iter(rows.into_iter().skip(1).map(move |r| {
Ok(rows
.into_iter()
.skip(1)
.map(move |r| {
//Each row is a dictionary with the headers as keys
match &r.value {
UntaggedValue::Row(d) => {
@ -100,9 +101,8 @@ pub async fn headers(args: CommandArgs) -> Result<OutputStream, ShellError> {
r.tag.span,
)),
}
}))
.to_output_stream(),
)
})
.to_output_stream())
}
#[cfg(test)]

View File

@ -18,7 +18,6 @@ pub struct HelpArgs {
rest: Vec<Tagged<String>>,
}
#[async_trait]
impl WholeStreamCommand for Help {
fn name(&self) -> &str {
"help"
@ -32,15 +31,15 @@ impl WholeStreamCommand for Help {
"Display help information about commands."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
help(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
help(args)
}
}
async fn help(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn help(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let scope = args.scope.clone();
let (HelpArgs { rest }, ..) = args.process().await?;
let (HelpArgs { rest }, ..) = args.process()?;
if !rest.is_empty() {
if rest[0].item == "commands" {
@ -155,7 +154,7 @@ async fn help(args: CommandArgs) -> Result<OutputStream, ShellError> {
ReturnSuccess::value(short_desc.into_value())
});
Ok(futures::stream::iter(iterator).to_output_stream())
Ok(iterator.to_output_stream())
} else if rest[0].item == "generate_docs" {
Ok(OutputStream::one(ReturnSuccess::value(generate_docs(
&scope,

View File

@ -8,7 +8,6 @@ use nu_source::Tagged;
pub struct Histogram;
#[async_trait]
impl WholeStreamCommand for Histogram {
fn name(&self) -> &str {
"histogram"
@ -32,8 +31,8 @@ impl WholeStreamCommand for Histogram {
"Creates a new table with a histogram based on the column name passed in."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
histogram(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
histogram(args)
}
fn examples(&self) -> Vec<Example> {
@ -58,11 +57,11 @@ impl WholeStreamCommand for Histogram {
}
}
pub async fn histogram(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn histogram(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let (input, args) = args.evaluate_once().await?.parts();
let (input, args) = args.evaluate_once()?.parts();
let values: Vec<Value> = input.collect().await;
let values: Vec<Value> = input.collect();
let mut columns = args
.positional_iter()
@ -114,73 +113,71 @@ pub async fn histogram(args: CommandArgs) -> Result<OutputStream, ShellError> {
let labels = results.labels.y.clone();
let mut idx = 0;
Ok(futures::stream::iter(
results
.data
.table_entries()
.cloned()
.collect::<Vec<_>>()
.into_iter()
.zip(
results
.percentages
.table_entries()
.cloned()
.collect::<Vec<_>>()
.into_iter(),
)
.map(move |(counts, percentages)| {
let percentage = percentages
.table_entries()
.cloned()
.last()
.unwrap_or_else(|| {
UntaggedValue::decimal_from_float(0.0, name.span).into_value(&name)
});
let value = counts
.table_entries()
.cloned()
.last()
.unwrap_or_else(|| UntaggedValue::int(0).into_value(&name));
Ok(results
.data
.table_entries()
.cloned()
.collect::<Vec<_>>()
.into_iter()
.zip(
results
.percentages
.table_entries()
.cloned()
.collect::<Vec<_>>()
.into_iter(),
)
.map(move |(counts, percentages)| {
let percentage = percentages
.table_entries()
.cloned()
.last()
.unwrap_or_else(|| {
UntaggedValue::decimal_from_float(0.0, name.span).into_value(&name)
});
let value = counts
.table_entries()
.cloned()
.last()
.unwrap_or_else(|| UntaggedValue::int(0).into_value(&name));
let mut fact = TaggedDictBuilder::new(&name);
let column_value = labels
.get(idx)
.ok_or_else(|| {
ShellError::labeled_error(
"Unable to load group labels",
"unable to load group labels",
&name,
)
})?
.clone();
let mut fact = TaggedDictBuilder::new(&name);
let column_value = labels
.get(idx)
.ok_or_else(|| {
ShellError::labeled_error(
"Unable to load group labels",
"unable to load group labels",
&name,
)
})?
.clone();
fact.insert_value(&column.item, column_value);
fact.insert_untagged("count", value);
fact.insert_value(&column.item, column_value);
fact.insert_untagged("count", value);
let fmt_percentage = format!(
"{}%",
// Some(2) < the number of digits
// true < group the digits
crate::commands::str_::from::action(&percentage, &name, Some(2), true)?
.as_string()?
);
fact.insert_untagged("percentage", UntaggedValue::string(fmt_percentage));
let fmt_percentage = format!(
"{}%",
// Some(2) < the number of digits
// true < group the digits
crate::commands::str_::from::action(&percentage, &name, Some(2), true)?
.as_string()?
);
fact.insert_untagged("percentage", UntaggedValue::string(fmt_percentage));
let string = std::iter::repeat("*")
.take(percentage.as_u64().map_err(|_| {
ShellError::labeled_error("expected a number", "expected a number", &name)
})? as usize)
.collect::<String>();
let string = std::iter::repeat("*")
.take(percentage.as_u64().map_err(|_| {
ShellError::labeled_error("expected a number", "expected a number", &name)
})? as usize)
.collect::<String>();
fact.insert_untagged(&frequency_column_name, UntaggedValue::string(string));
fact.insert_untagged(&frequency_column_name, UntaggedValue::string(string));
idx += 1;
idx += 1;
ReturnSuccess::value(fact.into_value())
}),
)
.to_output_stream())
ReturnSuccess::value(fact.into_value())
})
.to_output_stream())
}
fn evaluator(by: ColumnPath) -> Box<dyn Fn(usize, &Value) -> Result<Value, ShellError> + Send> {

View File

@ -13,7 +13,6 @@ struct Arguments {
pub struct History;
#[async_trait]
impl WholeStreamCommand for History {
fn name(&self) -> &str {
"history"
@ -27,15 +26,15 @@ impl WholeStreamCommand for History {
"Display command history."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
history(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
history(args)
}
}
async fn history(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn history(args: CommandArgs) -> Result<OutputStream, ShellError> {
let config: Box<dyn Conf> = Box::new(NuConfig::new());
let tag = args.call_info.name_tag.clone();
let (Arguments { clear }, _) = args.process().await?;
let (Arguments { clear }, _) = args.process()?;
let path = nu_data::config::path::history_path(&config);
@ -55,7 +54,7 @@ async fn history(args: CommandArgs) -> Result<OutputStream, ShellError> {
Err(_) => None,
});
Ok(futures::stream::iter(output).to_output_stream())
Ok(output.to_output_stream())
} else {
Err(ShellError::labeled_error(
"Could not open history",

View File

@ -16,7 +16,6 @@ pub struct IfArgs {
else_case: CapturedBlock,
}
#[async_trait]
impl WholeStreamCommand for If {
fn name(&self) -> &str {
"if"
@ -45,8 +44,8 @@ impl WholeStreamCommand for If {
"Run blocks if a condition is true or false."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
if_command(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
if_command(args)
}
fn examples(&self) -> Vec<Example> {
@ -64,7 +63,7 @@ impl WholeStreamCommand for If {
]
}
}
async fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = raw_args.call_info.name_tag.clone();
let context = Arc::new(EvaluationContext::from_args(&raw_args));
@ -75,7 +74,7 @@ async fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
else_case,
},
input,
) = raw_args.process().await?;
) = raw_args.process()?;
let cond = {
if condition.block.block.len() != 1 {
return Err(ShellError::labeled_error(
@ -109,22 +108,22 @@ async fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
context.scope.add_vars(&condition.captured.entries);
//FIXME: should we use the scope that's brought in as well?
let condition = evaluate_baseline_expr(&cond, &*context).await;
let condition = evaluate_baseline_expr(&cond, &*context);
match condition {
Ok(condition) => match condition.as_bool() {
Ok(b) => {
let result = if b {
run_block(&then_case.block, &*context, input).await
run_block(&then_case.block, &*context, input)
} else {
run_block(&else_case.block, &*context, input).await
run_block(&else_case.block, &*context, input)
};
context.scope.exit_scope();
result.map(|x| x.to_output_stream())
}
Err(e) => Ok(futures::stream::iter(vec![Err(e)].into_iter()).to_output_stream()),
Err(e) => Ok(vec![Err(e)].into_iter().to_output_stream()),
},
Err(e) => Ok(futures::stream::iter(vec![Err(e)].into_iter()).to_output_stream()),
Err(e) => Ok(vec![Err(e)].into_iter().to_output_stream()),
}
}

View File

@ -7,8 +7,6 @@ use nu_protocol::{
};
use nu_value_ext::ValueExt;
use futures::stream::once;
pub struct Command;
#[derive(Deserialize)]
@ -17,7 +15,6 @@ pub struct Arguments {
value: Value,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"insert"
@ -37,8 +34,8 @@ impl WholeStreamCommand for Command {
"Insert a new column with a given value."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
insert(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
insert(args)
}
fn examples(&self) -> Vec<Example> {
@ -64,7 +61,7 @@ impl WholeStreamCommand for Command {
}
}
async fn process_row(
fn process_row(
context: Arc<EvaluationContext>,
input: Value,
mut value: Arc<Value>,
@ -78,19 +75,19 @@ async fn process_row(
tag: block_tag,
} => {
let for_block = input.clone();
let input_stream = once(async { Ok(for_block) }).to_input_stream();
let input_stream = vec![Ok(for_block)].into_iter().to_input_stream();
context.scope.enter_scope();
context.scope.add_vars(&block.captured.entries);
context.scope.add_var("$it", input.clone());
let result = run_block(&block.block, &*context, input_stream).await;
let result = run_block(&block.block, &*context, input_stream);
context.scope.exit_scope();
match result {
Ok(mut stream) => {
let values = stream.drain_vec().await;
let values = stream.drain_vec();
let errors = context.get_errors();
if let Some(error) = errors.first() {
@ -153,23 +150,21 @@ async fn process_row(
})
}
async fn insert(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
fn insert(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let context = Arc::new(EvaluationContext::from_args(&raw_args));
let (Arguments { column, value }, input) = raw_args.process().await?;
let (Arguments { column, value }, input) = raw_args.process()?;
let value = Arc::new(value);
let column = Arc::new(column);
Ok(input
.then(move |input| {
.map(move |input| {
let context = context.clone();
let value = value.clone();
let column = column.clone();
async {
match process_row(context, input, value, column).await {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
match process_row(context, input, value, column) {
Ok(s) => s,
Err(e) => OutputStream::one(Err(e)),
}
})
.flatten()

View File

@ -12,7 +12,6 @@ pub struct IntoIntArgs {
pub rest: Vec<Value>,
}
#[async_trait]
impl WholeStreamCommand for IntoInt {
fn name(&self) -> &str {
"into-int"
@ -26,8 +25,8 @@ impl WholeStreamCommand for IntoInt {
"Convert value to integer."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
into_int(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
into_int(args)
}
fn examples(&self) -> Vec<Example> {
@ -46,8 +45,8 @@ impl WholeStreamCommand for IntoInt {
}
}
async fn into_int(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (args, _): (IntoIntArgs, _) = args.process().await?;
fn into_int(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (args, _): (IntoIntArgs, _) = args.process()?;
let stream = args.rest.into_iter().map(|i| match i {
Value {
@ -71,7 +70,7 @@ async fn into_int(args: CommandArgs) -> Result<OutputStream, ShellError> {
_ => OutputStream::one(Ok(ReturnSuccess::Value(i))),
});
Ok(futures::stream::iter(stream).flatten().to_output_stream())
Ok(stream.flatten().to_output_stream())
}
#[cfg(test)]

View File

@ -11,7 +11,6 @@ pub struct Arguments {
rows: Option<Tagged<usize>>,
}
#[async_trait]
impl WholeStreamCommand for Command {
fn name(&self) -> &str {
"keep"
@ -29,8 +28,8 @@ impl WholeStreamCommand for Command {
"Keep the number of rows only."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
keep(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
keep(args)
}
fn examples(&self) -> Vec<Example> {
@ -54,8 +53,8 @@ impl WholeStreamCommand for Command {
}
}
async fn keep(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rows }, input) = args.process().await?;
fn keep(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { rows }, input) = args.process()?;
let rows_desired = if let Some(quantity) = rows {
*quantity
} else {

View File

@ -8,7 +8,6 @@ use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue,
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"keep until"
@ -28,10 +27,10 @@ impl WholeStreamCommand for SubCommand {
"Keeps rows until the condition matches."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let call_info = args.evaluate_once().await?;
let call_info = args.evaluate_once()?;
let block = call_info.args.expect_nth(0)?.clone();
@ -88,13 +87,11 @@ impl WholeStreamCommand for SubCommand {
ctx.scope.add_var("$it", item.clone());
trace!("ITEM = {:?}", item);
async move {
let result = evaluate_baseline_expr(&*condition, &*ctx).await;
ctx.scope.exit_scope();
trace!("RESULT = {:?}", result);
let result = evaluate_baseline_expr(&*condition, &*ctx);
ctx.scope.exit_scope();
trace!("RESULT = {:?}", result);
!matches!(result, Ok(ref v) if v.is_true())
}
!matches!(result, Ok(ref v) if v.is_true())
})
.to_output_stream())
}

View File

@ -7,7 +7,6 @@ use nu_protocol::{hir::ClassifiedCommand, Signature, SyntaxShape, UntaggedValue,
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"keep while"
@ -27,9 +26,9 @@ impl WholeStreamCommand for SubCommand {
"Keeps rows while the condition matches."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&args));
let call_info = args.evaluate_once().await?;
let call_info = args.evaluate_once()?;
let block = call_info.args.expect_nth(0)?.clone();
@ -87,13 +86,11 @@ impl WholeStreamCommand for SubCommand {
ctx.scope.add_vars(&captured.entries);
trace!("ITEM = {:?}", item);
async move {
let result = evaluate_baseline_expr(&*condition, &*ctx).await;
ctx.scope.exit_scope();
trace!("RESULT = {:?}", result);
let result = evaluate_baseline_expr(&*condition, &*ctx);
ctx.scope.exit_scope();
trace!("RESULT = {:?}", result);
matches!(result, Ok(ref v) if v.is_true())
}
matches!(result, Ok(ref v) if v.is_true())
})
.to_output_stream())
}

View File

@ -16,7 +16,6 @@ pub struct KillArgs {
pub signal: Option<Tagged<u32>>,
}
#[async_trait]
impl WholeStreamCommand for Kill {
fn name(&self) -> &str {
"kill"
@ -49,8 +48,8 @@ impl WholeStreamCommand for Kill {
"Kill a process using the process id."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
kill(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
kill(args)
}
fn examples(&self) -> Vec<Example> {
@ -74,7 +73,7 @@ impl WholeStreamCommand for Kill {
}
}
async fn kill(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn kill(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (
KillArgs {
pid,
@ -84,7 +83,7 @@ async fn kill(args: CommandArgs) -> Result<OutputStream, ShellError> {
signal,
},
..,
) = args.process().await?;
) = args.process()?;
let mut cmd = if cfg!(windows) {
let mut cmd = Command::new("taskkill");

View File

@ -11,7 +11,6 @@ pub struct LastArgs {
rows: Option<Tagged<u64>>,
}
#[async_trait]
impl WholeStreamCommand for Last {
fn name(&self) -> &str {
"last"
@ -29,8 +28,8 @@ impl WholeStreamCommand for Last {
"Show only the last number of rows."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
last(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
last(args)
}
fn examples(&self) -> Vec<Example> {
@ -53,9 +52,9 @@ impl WholeStreamCommand for Last {
}
}
async fn last(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (LastArgs { rows }, input) = args.process().await?;
let v: Vec<_> = input.into_vec().await;
fn last(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (LastArgs { rows }, input) = args.process()?;
let v: Vec<_> = input.into_vec();
let end_rows_desired = if let Some(quantity) = rows {
*quantity as usize
@ -71,7 +70,7 @@ async fn last(args: CommandArgs) -> Result<OutputStream, ShellError> {
let iter = v.into_iter().skip(beginning_rows_to_skip);
Ok(futures::stream::iter(iter).to_output_stream())
Ok((iter).to_output_stream())
}
#[cfg(test)]

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use futures::stream::StreamExt;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{Signature, UntaggedValue, Value};
@ -11,7 +11,6 @@ pub struct LengthArgs {
column: bool,
}
#[async_trait]
impl WholeStreamCommand for Length {
fn name(&self) -> &str {
"length"
@ -29,10 +28,10 @@ impl WholeStreamCommand for Length {
"Show the total number of rows or items."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (LengthArgs { column }, input) = args.process().await?;
let rows: Vec<Value> = input.collect().await;
let (LengthArgs { column }, input) = args.process()?;
let rows: Vec<Value> = input.collect();
let length = if column {
if rows.is_empty() {

View File

@ -14,7 +14,6 @@ pub struct LetArgs {
pub rhs: CapturedBlock,
}
#[async_trait]
impl WholeStreamCommand for Let {
fn name(&self) -> &str {
"let"
@ -35,8 +34,8 @@ impl WholeStreamCommand for Let {
"Create a variable and give it a value."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
letcmd(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
letcmd(args)
}
fn examples(&self) -> Vec<Example> {
@ -44,11 +43,11 @@ impl WholeStreamCommand for Let {
}
}
pub async fn letcmd(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn letcmd(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let ctx = EvaluationContext::from_args(&args);
let (LetArgs { name, rhs, .. }, _) = args.process().await?;
let (LetArgs { name, rhs, .. }, _) = args.process()?;
let (expr, captured) = {
if rhs.block.block.len() != 1 {
@ -82,14 +81,14 @@ pub async fn letcmd(args: CommandArgs) -> Result<OutputStream, ShellError> {
ctx.scope.enter_scope();
ctx.scope.add_vars(&captured.entries);
let value = evaluate_baseline_expr(&expr, &ctx).await;
let value = evaluate_baseline_expr(&expr, &ctx);
ctx.scope.exit_scope();
let value = value?;
let name = if name.item.starts_with('$') {
name.item.clone()
name.item
} else {
format!("${}", name.item)
};

View File

@ -14,7 +14,6 @@ pub struct LetEnvArgs {
pub rhs: CapturedBlock,
}
#[async_trait]
impl WholeStreamCommand for LetEnv {
fn name(&self) -> &str {
"let-env"
@ -39,8 +38,8 @@ impl WholeStreamCommand for LetEnv {
"Create an environment variable and give it a value."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
set_env(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
set_env(args)
}
fn examples(&self) -> Vec<Example> {
@ -48,11 +47,11 @@ impl WholeStreamCommand for LetEnv {
}
}
pub async fn set_env(args: CommandArgs) -> Result<OutputStream, ShellError> {
pub fn set_env(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let ctx = EvaluationContext::from_args(&args);
let (LetEnvArgs { name, rhs, .. }, _) = args.process().await?;
let (LetEnvArgs { name, rhs, .. }, _) = args.process()?;
let (expr, captured) = {
if rhs.block.block.len() != 1 {
@ -86,14 +85,14 @@ pub async fn set_env(args: CommandArgs) -> Result<OutputStream, ShellError> {
ctx.scope.enter_scope();
ctx.scope.add_vars(&captured.entries);
let value = evaluate_baseline_expr(&expr, &ctx).await;
let value = evaluate_baseline_expr(&expr, &ctx);
ctx.scope.exit_scope();
let value = value?;
let value = value.as_string()?;
let name = name.item.clone();
let name = name.item;
// Note: this is a special case for setting the context from a command
// In this case, if we don't set it now, we'll lose the scope that this

View File

@ -6,7 +6,6 @@ use parking_lot::Mutex;
pub struct Lines;
#[async_trait]
impl WholeStreamCommand for Lines {
fn name(&self) -> &str {
"lines"
@ -20,8 +19,8 @@ impl WholeStreamCommand for Lines {
"Split single string into rows, one per line."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
lines(args).await
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
lines(args)
}
fn examples(&self) -> Vec<Example> {
@ -43,83 +42,74 @@ fn ends_with_line_ending(st: &str) -> bool {
}
}
async fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
let leftover_string = Arc::new(Mutex::new(String::new()));
let args = args.evaluate_once().await?;
let args = args.evaluate_once()?;
let tag = args.name_tag();
let name_span = tag.span;
let eos = futures::stream::iter(vec![
UntaggedValue::Primitive(Primitive::EndOfStream).into_untagged_value()
]);
let eos = vec![UntaggedValue::Primitive(Primitive::EndOfStream).into_untagged_value()];
Ok(args
.input
.chain(eos)
.filter_map(move |item| {
let leftover_string = leftover_string.clone();
async move {
match item {
Value {
value: UntaggedValue::Primitive(Primitive::String(st)),
..
} => {
let mut leftover_string = leftover_string.lock();
match item {
Value {
value: UntaggedValue::Primitive(Primitive::String(st)),
..
} => {
let mut leftover_string = leftover_string.lock();
let mut buffer = leftover_string.clone();
buffer.push_str(&st);
let mut buffer = leftover_string.clone();
buffer.push_str(&st);
let mut lines: Vec<String> =
buffer.lines().map(|x| x.to_string()).collect();
let mut lines: Vec<String> = buffer.lines().map(|x| x.to_string()).collect();
leftover_string.clear();
leftover_string.clear();
if !ends_with_line_ending(&st) {
if let Some(last) = lines.pop() {
leftover_string.push_str(&last);
}
}
if !lines.is_empty() {
let success_lines: Vec<_> = lines
.iter()
.map(|x| {
ReturnSuccess::value(
UntaggedValue::string(x).into_untagged_value(),
)
})
.collect();
Some(futures::stream::iter(success_lines))
} else {
None
if !ends_with_line_ending(&st) {
if let Some(last) = lines.pop() {
leftover_string.push_str(&last);
}
}
Value {
value: UntaggedValue::Primitive(Primitive::EndOfStream),
..
} => {
let st = (&*leftover_string).lock().clone();
if !st.is_empty() {
Some(futures::stream::iter(vec![ReturnSuccess::value(
UntaggedValue::string(st).into_untagged_value(),
)]))
} else {
None
}
if !lines.is_empty() {
let success_lines: Vec<_> = lines
.iter()
.map(|x| {
ReturnSuccess::value(UntaggedValue::string(x).into_untagged_value())
})
.collect();
Some(success_lines)
} else {
None
}
Value {
tag: value_span, ..
} => Some(futures::stream::iter(vec![Err(
ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
),
)])),
}
Value {
value: UntaggedValue::Primitive(Primitive::EndOfStream),
..
} => {
let st = (&*leftover_string).lock().clone();
if !st.is_empty() {
Some(vec![ReturnSuccess::value(
UntaggedValue::string(st).into_untagged_value(),
)])
} else {
None
}
}
Value {
tag: value_span, ..
} => Some(vec![Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
))]),
}
})
.flatten()

View File

@ -5,7 +5,6 @@ use nu_protocol::{Signature, SyntaxShape};
pub struct Ls;
#[async_trait]
impl WholeStreamCommand for Ls {
fn name(&self) -> &str {
"ls"
@ -40,11 +39,11 @@ impl WholeStreamCommand for Ls {
"View the contents of the current or given path."
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let name = args.call_info.name_tag.clone();
let ctrl_c = args.ctrl_c.clone();
let shell_manager = args.shell_manager.clone();
let (args, _) = args.process().await?;
let (args, _) = args.process()?;
shell_manager.ls(args, name, ctrl_c)
}

View File

@ -33,7 +33,7 @@ macro_rules! command {
fn command($args: EvaluatedCommandArgs, ( $($param_name),*, ): ( $($param_type),*, )) -> Result<OutputStream, ShellError> {
let output = $body;
Ok(output.boxed().to_output_stream())
Ok(output.to_output_stream())
}
let $args = $args.evaluate_once(registry)?;

View File

@ -5,7 +5,6 @@ use nu_protocol::{Primitive, Signature, UntaggedValue, Value};
pub struct SubCommand;
#[async_trait]
impl WholeStreamCommand for SubCommand {
fn name(&self) -> &str {
"math abs"
@ -19,7 +18,7 @@ impl WholeStreamCommand for SubCommand {
"Returns absolute values of a list of numbers"
}
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let mapped = args.input.map(move |val| match val.value {
UntaggedValue::Primitive(Primitive::Int(val)) => {
UntaggedValue::int(val.magnitude().clone()).into()

Some files were not shown because too many files have changed in this diff Show More