From 935a5f6b9ed9e5127819746e2f5165d8700ba965 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Fri, 12 Jun 2020 01:34:41 -0700 Subject: [PATCH] Another batch of removing async_stream (#1970) --- crates/nu-cli/src/commands/alias.rs | 110 +++++++------ crates/nu-cli/src/commands/average.rs | 74 ++++----- crates/nu-cli/src/commands/enter.rs | 217 +++++++++++++------------- crates/nu-cli/src/commands/from.rs | 12 +- crates/nu-protocol/src/value.rs | 8 + 5 files changed, 217 insertions(+), 204 deletions(-) diff --git a/crates/nu-cli/src/commands/alias.rs b/crates/nu-cli/src/commands/alias.rs index b6948572c8..81ee024a36 100644 --- a/crates/nu-cli/src/commands/alias.rs +++ b/crates/nu-cli/src/commands/alias.rs @@ -45,8 +45,7 @@ impl WholeStreamCommand for Alias { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - // args.process(registry, alias)?.run() - alias(args, registry) + alias(args, registry).await } fn examples(&self) -> Vec { @@ -65,63 +64,78 @@ impl WholeStreamCommand for Alias { } } -// <<<<<<< HEAD -// pub fn alias(alias_args: AliasArgs, ctx: RunnableContext) -> Result { -// ======= -pub fn alias(args: CommandArgs, registry: &CommandRegistry) -> Result { +pub async fn alias( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { let registry = registry.clone(); - let stream = async_stream! { - let mut raw_input = args.raw_input.clone(); - let (AliasArgs { name, args: list, block, save}, ctx) = args.process(®istry).await?; - let mut processed_args: Vec = vec![]; + let mut raw_input = args.raw_input.clone(); + let ( + AliasArgs { + name, + args: list, + block, + save, + }, + _ctx, + ) = args.process(®istry).await?; + let mut processed_args: Vec = vec![]; - if let Some(true) = save { - let mut result = crate::data::config::read(name.clone().tag, &None)?; + if let Some(true) = save { + let mut result = crate::data::config::read(name.clone().tag, &None)?; - // process the alias to remove the --save flag - let left_brace = raw_input.find('{').unwrap_or(0); - let right_brace = raw_input.rfind('}').unwrap_or(raw_input.len()); - let mut left = raw_input[..left_brace].replace("--save", "").replace("-s", ""); - let mut right = raw_input[right_brace..].replace("--save", "").replace("-s", ""); - raw_input = format!("{}{}{}", left, &raw_input[left_brace..right_brace], right); + // process the alias to remove the --save flag + let left_brace = raw_input.find('{').unwrap_or(0); + let right_brace = raw_input.rfind('}').unwrap_or_else(|| raw_input.len()); + let left = raw_input[..left_brace] + .replace("--save", "") + .replace("-s", ""); + let right = raw_input[right_brace..] + .replace("--save", "") + .replace("-s", ""); + raw_input = format!("{}{}{}", left, &raw_input[left_brace..right_brace], right); - // create a value from raw_input alias - let alias: Value = raw_input.trim().to_string().into(); - let alias_start = raw_input.find("[").unwrap_or(0); // used to check if the same alias already exists + // create a value from raw_input alias + let alias: Value = raw_input.trim().to_string().into(); + let alias_start = raw_input.find('[').unwrap_or(0); // used to check if the same alias already exists - // add to startup if alias doesn't exist and replce if it does - match result.get_mut("startup") { - Some(startup) => { - if let UntaggedValue::Table(ref mut commands) = startup.value { - if let Some(command) = commands.iter_mut().find(|command| { - let cmd_str = command.as_string().unwrap_or_default(); - cmd_str.starts_with(&raw_input[..alias_start]) - }) { - *command = alias; - } else { - commands.push(alias); - } + // add to startup if alias doesn't exist and replce if it does + match result.get_mut("startup") { + Some(startup) => { + if let UntaggedValue::Table(ref mut commands) = startup.value { + if let Some(command) = commands.iter_mut().find(|command| { + let cmd_str = command.as_string().unwrap_or_default(); + cmd_str.starts_with(&raw_input[..alias_start]) + }) { + *command = alias; + } else { + commands.push(alias); } } - None => { - let mut table = UntaggedValue::table(&[alias]); - result.insert("startup".to_string(), table.into_value(Tag::default())); - } } - config::write(&result, &None)?; - } - - for item in list.iter() { - if let Ok(string) = item.as_string() { - processed_args.push(format!("${}", string)); - } else { - yield Err(ShellError::labeled_error("Expected a string", "expected a string", item.tag())); + None => { + let table = UntaggedValue::table(&[alias]); + result.insert("startup".to_string(), table.into_value(Tag::default())); } } - yield ReturnSuccess::action(CommandAction::AddAlias(name.to_string(), processed_args, block.clone())) - }; + config::write(&result, &None)?; + } - Ok(stream.to_output_stream()) + for item in list.iter() { + if let Ok(string) = item.as_string() { + processed_args.push(format!("${}", string)); + } else { + return Err(ShellError::labeled_error( + "Expected a string", + "expected a string", + item.tag(), + )); + } + } + + Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::AddAlias(name.to_string(), processed_args, block), + ))) } #[cfg(test)] diff --git a/crates/nu-cli/src/commands/average.rs b/crates/nu-cli/src/commands/average.rs index 80b786b6ff..d7363f3c25 100644 --- a/crates/nu-cli/src/commands/average.rs +++ b/crates/nu-cli/src/commands/average.rs @@ -4,9 +4,7 @@ use crate::utils::data_processing::{reducer_for, Reduce}; use bigdecimal::FromPrimitive; use nu_errors::ShellError; use nu_protocol::hir::{convert_number_to_u64, Number, Operator}; -use nu_protocol::{ - Dictionary, Primitive, ReturnSuccess, ReturnValue, Signature, UntaggedValue, Value, -}; +use nu_protocol::{Dictionary, Primitive, ReturnSuccess, Signature, UntaggedValue, Value}; use num_traits::identities::Zero; use indexmap::map::IndexMap; @@ -42,6 +40,7 @@ impl WholeStreamCommand for Average { name: args.call_info.name_tag, raw_input: args.raw_input, }) + .await } fn examples(&self) -> Vec { @@ -53,53 +52,48 @@ impl WholeStreamCommand for Average { } } -fn average( +async fn average( RunnableContext { mut input, name, .. }: RunnableContext, ) -> Result { - let stream = async_stream! { - let mut values: Vec = input.drain_vec().await; - let action = reducer_for(Reduce::Sum); + let values: Vec = input.drain_vec().await; - if values.iter().all(|v| if let UntaggedValue::Primitive(_) = v.value {true} else {false}) { - match avg(&values, name) { - Ok(result) => yield ReturnSuccess::value(result), - Err(err) => yield Err(err), - } - } else { - let mut column_values = IndexMap::new(); - for value in values { - match value.value { - UntaggedValue::Row(row_dict) => { - for (key, value) in row_dict.entries.iter() { - column_values - .entry(key.clone()) - .and_modify(|v: &mut Vec| v.push(value.clone())) - .or_insert(vec![value.clone()]); - } - }, - table => {}, - }; - } - - let mut column_totals = IndexMap::new(); - for (col_name, col_vals) in column_values { - match avg(&col_vals, &name) { - Ok(result) => { - column_totals.insert(col_name, result); - } - Err(err) => yield Err(err), + if values.iter().all(|v| v.is_primitive()) { + match avg(&values, name) { + Ok(result) => Ok(OutputStream::one(ReturnSuccess::value(result))), + Err(err) => Err(err), + } + } else { + let mut column_values = IndexMap::new(); + for value in values { + if let UntaggedValue::Row(row_dict) = value.value { + for (key, value) in row_dict.entries.iter() { + column_values + .entry(key.clone()) + .and_modify(|v: &mut Vec| v.push(value.clone())) + .or_insert(vec![value.clone()]); } } - yield ReturnSuccess::value( - UntaggedValue::Row(Dictionary {entries: column_totals}).into_untagged_value()) } - }; - let stream: BoxStream<'static, ReturnValue> = stream.boxed(); + let mut column_totals = IndexMap::new(); + for (col_name, col_vals) in column_values { + match avg(&col_vals, &name) { + Ok(result) => { + column_totals.insert(col_name, result); + } + Err(err) => return Err(err), + } + } - Ok(stream.to_output_stream()) + Ok(OutputStream::one(ReturnSuccess::value( + UntaggedValue::Row(Dictionary { + entries: column_totals, + }) + .into_untagged_value(), + ))) + } } fn avg(values: &[Value], name: impl Into) -> Result { diff --git a/crates/nu-cli/src/commands/enter.rs b/crates/nu-cli/src/commands/enter.rs index ae59a87308..4f60741422 100644 --- a/crates/nu-cli/src/commands/enter.rs +++ b/crates/nu-cli/src/commands/enter.rs @@ -54,7 +54,7 @@ documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"# args: CommandArgs, registry: &CommandRegistry, ) -> Result { - enter(args, registry) + enter(args, registry).await } fn examples(&self) -> Vec { @@ -78,121 +78,122 @@ documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"# } } -fn enter(raw_args: CommandArgs, registry: &CommandRegistry) -> Result { +async fn enter( + raw_args: CommandArgs, + registry: &CommandRegistry, +) -> Result { let registry = registry.clone(); - let stream = async_stream! { - let scope = raw_args.call_info.scope.clone(); - let shell_manager = raw_args.shell_manager.clone(); - let head = raw_args.call_info.args.head.clone(); - let ctrl_c = raw_args.ctrl_c.clone(); - 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(®istry).await?; - let location_string = location.display().to_string(); - let location_clone = location_string.clone(); + let scope = raw_args.call_info.scope.clone(); + let shell_manager = raw_args.shell_manager.clone(); + let head = raw_args.call_info.args.head.clone(); + let ctrl_c = raw_args.ctrl_c.clone(); + 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(®istry).await?; + let location_string = location.display().to_string(); + let location_clone = location_string.clone(); - if location_string.starts_with("help") { - let spec = location_string.split(':').collect::>(); + if location_string.starts_with("help") { + let spec = location_string.split(':').collect::>(); - if spec.len() == 2 { - let (_, command) = (spec[0], spec[1]); + if spec.len() == 2 { + let (_, command) = (spec[0], spec[1]); - if registry.has(command) { - yield Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell( + if registry.has(command) { + return Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::EnterHelpShell( UntaggedValue::string(command).into_value(Tag::unknown()), - ))); - return; - } - } - yield Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell( - UntaggedValue::nothing().into_value(Tag::unknown()), - ))); - } else if location.is_dir() { - yield Ok(ReturnSuccess::Action(CommandAction::EnterShell( - location_clone, - ))); - } else { - // If it's a file, attempt to open the file as a value and enter it - let cwd = shell_manager.path(); - - let full_path = std::path::PathBuf::from(cwd); - - let (file_extension, contents, contents_tag) = - crate::commands::open::fetch( - &full_path, - &PathBuf::from(location_clone), - tag.span, - match encoding { - Some(e) => e.to_string(), - _ => "".to_string() - } - ).await?; - - match contents { - UntaggedValue::Primitive(Primitive::String(_)) => { - let tagged_contents = contents.into_value(&contents_tag); - - if let Some(extension) = file_extension { - let command_name = format!("from {}", extension); - if let Some(converter) = - registry.get_command(&command_name) - { - let new_args = RawCommandArgs { - host, - ctrl_c, - current_errors, - shell_manager, - call_info: UnevaluatedCallInfo { - args: nu_protocol::hir::Call { - head, - positional: None, - named: None, - span: Span::unknown(), - is_last: false, - }, - name_tag: tag.clone(), - scope: scope.clone() - }, - }; - let mut result = converter.run( - new_args.with_input(vec![tagged_contents]), - ®istry, - ).await; - let result_vec: Vec> = - result.drain_vec().await; - for res in result_vec { - match res { - Ok(ReturnSuccess::Value(Value { - value, - .. - })) => { - yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell( - Value { - value, - tag: contents_tag.clone(), - }))); - } - x => yield x, - } - } - } else { - yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents))); - } - } else { - yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents))); - } - } - _ => { - let tagged_contents = contents.into_value(contents_tag); - - yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents))); - } + ), + ))); } } - }; + Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::EnterHelpShell(UntaggedValue::nothing().into_value(Tag::unknown())), + ))) + } else if location.is_dir() { + Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::EnterShell(location_clone), + ))) + } else { + // If it's a file, attempt to open the file as a value and enter it + let cwd = shell_manager.path(); - Ok(stream.to_output_stream()) + let full_path = std::path::PathBuf::from(cwd); + + let (file_extension, contents, contents_tag) = crate::commands::open::fetch( + &full_path, + &PathBuf::from(location_clone), + tag.span, + match encoding { + Some(e) => e.to_string(), + _ => "".to_string(), + }, + ) + .await?; + + match contents { + UntaggedValue::Primitive(Primitive::String(_)) => { + let tagged_contents = contents.into_value(&contents_tag); + + if let Some(extension) = file_extension { + let command_name = format!("from {}", extension); + if let Some(converter) = registry.get_command(&command_name) { + let new_args = RawCommandArgs { + host, + ctrl_c, + current_errors, + shell_manager, + call_info: UnevaluatedCallInfo { + args: nu_protocol::hir::Call { + head, + positional: None, + named: None, + span: Span::unknown(), + is_last: false, + }, + name_tag: tag.clone(), + scope: scope.clone(), + }, + }; + let mut result = converter + .run(new_args.with_input(vec![tagged_contents]), ®istry) + .await; + let result_vec: Vec> = + result.drain_vec().await; + + Ok(futures::stream::iter(result_vec.into_iter().map( + move |res| match res { + Ok(ReturnSuccess::Value(Value { value, .. })) => Ok( + ReturnSuccess::Action(CommandAction::EnterValueShell(Value { + value, + tag: contents_tag.clone(), + })), + ), + x => x, + }, + )) + .to_output_stream()) + } else { + Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::EnterValueShell(tagged_contents), + ))) + } + } else { + Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::EnterValueShell(tagged_contents), + ))) + } + } + _ => { + let tagged_contents = contents.into_value(contents_tag); + + Ok(OutputStream::one(ReturnSuccess::action( + CommandAction::EnterValueShell(tagged_contents), + ))) + } + } + } } #[cfg(test)] diff --git a/crates/nu-cli/src/commands/from.rs b/crates/nu-cli/src/commands/from.rs index 121451ade7..e5ee313707 100644 --- a/crates/nu-cli/src/commands/from.rs +++ b/crates/nu-cli/src/commands/from.rs @@ -25,14 +25,10 @@ impl WholeStreamCommand for From { registry: &CommandRegistry, ) -> Result { let registry = registry.clone(); - let stream = async_stream! { - yield Ok(ReturnSuccess::Value( - UntaggedValue::string(crate::commands::help::get_help(&From, ®istry)) - .into_value(Tag::unknown()), - )); - }; - - Ok(stream.to_output_stream()) + Ok(OutputStream::one(ReturnSuccess::value( + UntaggedValue::string(crate::commands::help::get_help(&From, ®istry)) + .into_value(Tag::unknown()), + ))) } } diff --git a/crates/nu-protocol/src/value.rs b/crates/nu-protocol/src/value.rs index 9852c89414..acef9d86cf 100644 --- a/crates/nu-protocol/src/value.rs +++ b/crates/nu-protocol/src/value.rs @@ -339,6 +339,14 @@ impl Value { } } + /// View the Value as a Primitive value, if possible + pub fn is_primitive(&self) -> bool { + match &self.value { + UntaggedValue::Primitive(_) => true, + _ => false, + } + } + /// View the Value as unsigned 64-bit, if possible pub fn as_u64(&self) -> Result { match &self.value {