mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
parent
ad1c4f5e39
commit
073e5727c6
262 changed files with 2269 additions and 2660 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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()),
|
||||
)))
|
||||
|
|
|
@ -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: _,
|
||||
|
|
|
@ -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: _,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)),
|
||||
})
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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()),
|
||||
)))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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()),
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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()?
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()),
|
||||
)))
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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,
|
||||
))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)),
|
||||
},
|
||||
)
|
||||
|
|
|
@ -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)),
|
||||
},
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(|_| {
|
||||
|
|
|
@ -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)),
|
||||
},
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()),
|
||||
)))
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue