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 crate::prelude::*;
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Arguments {
|
struct Arguments {
|
||||||
@ -27,13 +27,14 @@ impl WholeStreamCommand for Command {
|
|||||||
"Append a row to the table."
|
"Append a row to the table."
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let (Arguments { mut value }, input) = args.process()?;
|
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();
|
value.tag = first.tag();
|
||||||
|
prepend.push(first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if we are trying to append a row literal
|
// Checks if we are trying to append a row literal
|
||||||
@ -47,11 +48,10 @@ impl WholeStreamCommand for Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(input
|
Ok(prepend
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(vec![value])
|
.chain(input.into_iter().chain(vec![value]))
|
||||||
.map(ReturnSuccess::value)
|
.to_output_stream())
|
||||||
.to_action_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, ReturnValue, Signature, UntaggedValue};
|
use nu_protocol::{Signature, UntaggedValue, Value};
|
||||||
|
|
||||||
pub struct Length;
|
pub struct Length;
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ impl WholeStreamCommand for Length {
|
|||||||
"Show the total number of rows or items."
|
"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 tag = args.call_info.name_tag.clone();
|
||||||
let (LengthArgs { column }, input) = args.process()?;
|
let (LengthArgs { column }, input) = args.process()?;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ impl WholeStreamCommand for Length {
|
|||||||
done: false,
|
done: false,
|
||||||
tag,
|
tag,
|
||||||
}
|
}
|
||||||
.to_action_stream())
|
.to_output_stream())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -65,7 +65,7 @@ struct CountIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for CountIterator {
|
impl Iterator for CountIterator {
|
||||||
type Item = ReturnValue;
|
type Item = Value;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.done {
|
if self.done {
|
||||||
@ -79,7 +79,7 @@ impl Iterator for CountIterator {
|
|||||||
match &first.value {
|
match &first.value {
|
||||||
UntaggedValue::Row(dictionary) => dictionary.length(),
|
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",
|
||||||
"cannot obtain column length",
|
"cannot obtain column length",
|
||||||
self.tag.clone(),
|
self.tag.clone(),
|
||||||
@ -94,9 +94,7 @@ impl Iterator for CountIterator {
|
|||||||
input.count()
|
input.count()
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Ok(ReturnSuccess::Value(
|
Some(UntaggedValue::int(length).into_value(self.tag.clone()))
|
||||||
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."
|
"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)
|
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 (PrependArgs { row }, input) = args.process()?;
|
||||||
|
|
||||||
let bos = vec![row].into_iter();
|
let bos = vec![row].into_iter();
|
||||||
|
|
||||||
Ok(bos.chain(input).to_action_stream())
|
Ok(bos.chain(input).to_output_stream())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -3,7 +3,9 @@ use nu_engine::evaluate_baseline_expr;
|
|||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::CapturedBlock, hir::ClassifiedCommand, ReturnSuccess, Signature, SyntaxShape,
|
hir::CapturedBlock,
|
||||||
|
hir::{ClassifiedCommand, SpannedExpression},
|
||||||
|
Signature, SyntaxShape, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Command;
|
pub struct Command;
|
||||||
@ -30,7 +32,7 @@ impl WholeStreamCommand for Command {
|
|||||||
"Filter table to match the condition."
|
"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)
|
where_command(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +61,8 @@ impl WholeStreamCommand for Command {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn where_command(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
fn where_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let ctx = Arc::new(EvaluationContext::from_args(&raw_args));
|
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||||
let tag = raw_args.call_info.name_tag.clone();
|
let tag = raw_args.call_info.name_tag.clone();
|
||||||
let (Arguments { block }, input) = raw_args.process()?;
|
let (Arguments { block }, input) = raw_args.process()?;
|
||||||
let condition = {
|
let condition = {
|
||||||
@ -92,34 +94,13 @@ fn where_command(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(input
|
Ok(WhereIterator {
|
||||||
.filter_map(move |input| {
|
block,
|
||||||
let condition = condition.clone();
|
condition,
|
||||||
let ctx = ctx.clone();
|
context,
|
||||||
|
input,
|
||||||
ctx.scope.enter_scope();
|
}
|
||||||
ctx.scope.add_vars(&block.captured.entries);
|
.to_output_stream())
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => Some(Err(e)),
|
|
||||||
},
|
|
||||||
Err(e) => Some(Err(e)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.to_action_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -134,3 +115,40 @@ mod tests {
|
|||||||
test_examples(Command {})
|
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