mirror of
https://github.com/nushell/nushell
synced 2024-12-29 06:23:11 +00:00
Another batch of removing async_stream (#1970)
This commit is contained in:
parent
731aa6bbdd
commit
935a5f6b9e
5 changed files with 217 additions and 204 deletions
|
@ -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(®istry).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(®istry).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)]
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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(®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::<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]),
|
||||
®istry,
|
||||
).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]), ®istry)
|
||||
.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)]
|
||||
|
|
|
@ -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, ®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()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue