Another batch of removing async_stream (#1970)

This commit is contained in:
Jonathan Turner 2020-06-12 01:34:41 -07:00 committed by GitHub
parent 731aa6bbdd
commit 935a5f6b9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 217 additions and 204 deletions

View file

@ -45,8 +45,7 @@ impl WholeStreamCommand for Alias {
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
// args.process(registry, alias)?.run()
alias(args, registry)
alias(args, registry).await
}
fn examples(&self) -> Vec<Example> {
@ -65,63 +64,78 @@ impl WholeStreamCommand for Alias {
}
}
// <<<<<<< HEAD
// pub fn alias(alias_args: AliasArgs, ctx: RunnableContext) -> Result<OutputStream, ShellError> {
// =======
pub fn alias(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
pub async fn alias(
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
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(&registry).await?;
let mut processed_args: Vec<String> = vec![];
let mut raw_input = args.raw_input.clone();
let (
AliasArgs {
name,
args: list,
block,
save,
},
_ctx,
) = args.process(&registry).await?;
let mut processed_args: Vec<String> = 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)]

View file

@ -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<Example> {
@ -53,53 +52,48 @@ impl WholeStreamCommand for Average {
}
}
fn average(
async fn average(
RunnableContext {
mut input, name, ..
}: RunnableContext,
) -> Result<OutputStream, ShellError> {
let stream = async_stream! {
let mut values: Vec<Value> = input.drain_vec().await;
let action = reducer_for(Reduce::Sum);
let values: Vec<Value> = 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<Value>| 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<Value>| 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<Tag>) -> Result<Value, ShellError> {

View file

@ -54,7 +54,7 @@ documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"#
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
enter(args, registry)
enter(args, registry).await
}
fn examples(&self) -> Vec<Example> {
@ -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<OutputStream, ShellError> {
async fn enter(
raw_args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
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(&registry).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(&registry).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::<Vec<&str>>();
if location_string.starts_with("help") {
let spec = location_string.split(':').collect::<Vec<&str>>();
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]),
&registry,
).await;
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
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]), &registry)
.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 {
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)]

View file

@ -25,14 +25,10 @@ impl WholeStreamCommand for From {
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
let registry = registry.clone();
let stream = async_stream! {
yield Ok(ReturnSuccess::Value(
UntaggedValue::string(crate::commands::help::get_help(&From, &registry))
.into_value(Tag::unknown()),
));
};
Ok(stream.to_output_stream())
Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(crate::commands::help::get_help(&From, &registry))
.into_value(Tag::unknown()),
)))
}
}

View file

@ -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<u64, ShellError> {
match &self.value {