Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A few optimisations #3306

Merged
merged 2 commits into from Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 9 additions & 9 deletions crates/nu-command/src/commands/append.rs
@@ -1,7 +1,7 @@
use crate::prelude::*;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};

#[derive(Deserialize)]
struct Arguments {
Expand All @@ -27,13 +27,14 @@ impl WholeStreamCommand for Command {
"Append a row to the table."
}

fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
let (Arguments { mut value }, input) = args.process()?;
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let (Arguments { mut value }, mut input) = args.process()?;

let input: Vec<Value> = input.collect();
let mut prepend = vec![];

if let Some(first) = input.get(0) {
if let Some(first) = input.next() {
value.tag = first.tag();
prepend.push(first);
}

// Checks if we are trying to append a row literal
Expand All @@ -47,11 +48,10 @@ impl WholeStreamCommand for Command {
}
}

Ok(input
Ok(prepend
.into_iter()
.chain(vec![value])
.map(ReturnSuccess::value)
.to_action_stream())
.chain(input.into_iter().chain(vec![value]))
.to_output_stream())
}

fn examples(&self) -> Vec<Example> {
Expand Down
14 changes: 6 additions & 8 deletions crates/nu-command/src/commands/length.rs
Expand Up @@ -2,7 +2,7 @@ use crate::prelude::*;

use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{ReturnSuccess, ReturnValue, Signature, UntaggedValue};
use nu_protocol::{Signature, UntaggedValue, Value};

pub struct Length;

Expand All @@ -28,7 +28,7 @@ impl WholeStreamCommand for Length {
"Show the total number of rows or items."
}

fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.name_tag.clone();
let (LengthArgs { column }, input) = args.process()?;

Expand All @@ -38,7 +38,7 @@ impl WholeStreamCommand for Length {
done: false,
tag,
}
.to_action_stream())
.to_output_stream())
}

fn examples(&self) -> Vec<Example> {
Expand All @@ -65,7 +65,7 @@ struct CountIterator {
}

impl Iterator for CountIterator {
type Item = ReturnValue;
type Item = Value;

fn next(&mut self) -> Option<Self::Item> {
if self.done {
Expand All @@ -79,7 +79,7 @@ impl Iterator for CountIterator {
match &first.value {
UntaggedValue::Row(dictionary) => dictionary.length(),
_ => {
return Some(Err(ShellError::labeled_error(
return Some(Value::error(ShellError::labeled_error(
"Cannot obtain column length",
"cannot obtain column length",
self.tag.clone(),
Expand All @@ -94,9 +94,7 @@ impl Iterator for CountIterator {
input.count()
};

Some(Ok(ReturnSuccess::Value(
UntaggedValue::int(length).into_value(self.tag.clone()),
)))
Some(UntaggedValue::int(length).into_value(self.tag.clone()))
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/nu-command/src/commands/prepend.rs
Expand Up @@ -27,7 +27,7 @@ impl WholeStreamCommand for Prepend {
"Prepend the given row to the front of the table."
}

fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
prepend(args)
}

Expand All @@ -45,12 +45,12 @@ impl WholeStreamCommand for Prepend {
}
}

fn prepend(args: CommandArgs) -> Result<ActionStream, ShellError> {
fn prepend(args: CommandArgs) -> Result<OutputStream, ShellError> {
let (PrependArgs { row }, input) = args.process()?;

let bos = vec![row].into_iter();

Ok(bos.chain(input).to_action_stream())
Ok(bos.chain(input).to_output_stream())
}

#[cfg(test)]
Expand Down
80 changes: 49 additions & 31 deletions crates/nu-command/src/commands/where_.rs
Expand Up @@ -3,7 +3,9 @@ use nu_engine::evaluate_baseline_expr;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_protocol::{
hir::CapturedBlock, hir::ClassifiedCommand, ReturnSuccess, Signature, SyntaxShape,
hir::CapturedBlock,
hir::{ClassifiedCommand, SpannedExpression},
Signature, SyntaxShape, Value,
};

pub struct Command;
Expand All @@ -30,7 +32,7 @@ impl WholeStreamCommand for Command {
"Filter table to match the condition."
}

fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
where_command(args)
}

Expand Down Expand Up @@ -59,8 +61,8 @@ impl WholeStreamCommand for Command {
]
}
}
fn where_command(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
let ctx = Arc::new(EvaluationContext::from_args(&raw_args));
fn where_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
let context = Arc::new(EvaluationContext::from_args(&raw_args));
let tag = raw_args.call_info.name_tag.clone();
let (Arguments { block }, input) = raw_args.process()?;
let condition = {
Expand Down Expand Up @@ -92,45 +94,61 @@ fn where_command(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
}
};

Ok(input
.filter_map(move |input| {
let condition = condition.clone();
let ctx = ctx.clone();
Ok(WhereIterator {
block,
condition,
context,
input,
}
.to_output_stream())
}

#[cfg(test)]
mod tests {
use super::Command;
use super::ShellError;

#[test]
fn examples_work_as_expected() -> Result<(), ShellError> {
use crate::examples::test as test_examples;

ctx.scope.enter_scope();
ctx.scope.add_vars(&block.captured.entries);
ctx.scope.add_var("$it", input.clone());
test_examples(Command {})
}
}

struct WhereIterator {
condition: Box<SpannedExpression>,
context: Arc<EvaluationContext>,
input: InputStream,
block: CapturedBlock,
}

impl Iterator for WhereIterator {
type Item = Value;

fn next(&mut self) -> Option<Self::Item> {
while let Some(x) = self.input.next() {
self.context.scope.enter_scope();
self.context.scope.add_vars(&self.block.captured.entries);
self.context.scope.add_var("$it", x.clone());

//FIXME: should we use the scope that's brought in as well?
let condition = evaluate_baseline_expr(&condition, &*ctx);
ctx.scope.exit_scope();
let condition = evaluate_baseline_expr(&self.condition, &self.context);
self.context.scope.exit_scope();

match condition {
Ok(condition) => match condition.as_bool() {
Ok(b) => {
if b {
Some(Ok(ReturnSuccess::Value(input)))
} else {
None
return Some(x);
}
}
Err(e) => Some(Err(e)),
Err(e) => return Some(Value::error(e)),
},
Err(e) => Some(Err(e)),
Err(e) => return Some(Value::error(e)),
}
})
.to_action_stream())
}

#[cfg(test)]
mod tests {
use super::Command;
use super::ShellError;

#[test]
fn examples_work_as_expected() -> Result<(), ShellError> {
use crate::examples::test as test_examples;
}

test_examples(Command {})
None
}
}