mirror of
https://github.com/nushell/nushell.git
synced 2024-12-23 23:49:44 +01:00
parent
b2fe5fabb1
commit
fc15e0e27d
@ -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 {
|
||||
@ -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
|
||||
@ -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> {
|
||||
|
@ -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;
|
||||
|
||||
@ -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()?;
|
||||
|
||||
@ -38,7 +38,7 @@ impl WholeStreamCommand for Length {
|
||||
done: false,
|
||||
tag,
|
||||
}
|
||||
.to_action_stream())
|
||||
.to_output_stream())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -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 {
|
||||
@ -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(),
|
||||
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
@ -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)]
|
||||
|
@ -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;
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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 = {
|
||||
@ -92,34 +94,13 @@ fn where_command(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
}
|
||||
};
|
||||
|
||||
Ok(input
|
||||
.filter_map(move |input| {
|
||||
let condition = condition.clone();
|
||||
let ctx = ctx.clone();
|
||||
|
||||
ctx.scope.enter_scope();
|
||||
ctx.scope.add_vars(&block.captured.entries);
|
||||
ctx.scope.add_var("$it", input.clone());
|
||||
|
||||
//FIXME: should we use the scope that's brought in as well?
|
||||
let condition = evaluate_baseline_expr(&condition, &*ctx);
|
||||
ctx.scope.exit_scope();
|
||||
|
||||
match condition {
|
||||
Ok(condition) => match condition.as_bool() {
|
||||
Ok(b) => {
|
||||
if b {
|
||||
Some(Ok(ReturnSuccess::Value(input)))
|
||||
} else {
|
||||
None
|
||||
Ok(WhereIterator {
|
||||
block,
|
||||
condition,
|
||||
context,
|
||||
input,
|
||||
}
|
||||
}
|
||||
Err(e) => Some(Err(e)),
|
||||
},
|
||||
Err(e) => Some(Err(e)),
|
||||
}
|
||||
})
|
||||
.to_action_stream())
|
||||
.to_output_stream())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -134,3 +115,40 @@ mod tests {
|
||||
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(&self.condition, &self.context);
|
||||
self.context.scope.exit_scope();
|
||||
|
||||
match condition {
|
||||
Ok(condition) => match condition.as_bool() {
|
||||
Ok(b) => {
|
||||
if b {
|
||||
return Some(x);
|
||||
}
|
||||
}
|
||||
Err(e) => return Some(Value::error(e)),
|
||||
},
|
||||
Err(e) => return Some(Value::error(e)),
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user