forked from extern/nushell
Add row conditions
This commit is contained in:
@ -5,7 +5,9 @@ use nu_protocol::{
|
||||
Signature, SyntaxShape,
|
||||
};
|
||||
|
||||
use crate::{Alias, Benchmark, BuildString, Def, Do, Each, For, If, Length, Let, LetEnv};
|
||||
use crate::{
|
||||
where_::Where, Alias, Benchmark, BuildString, Def, Do, Each, For, If, Length, Let, LetEnv,
|
||||
};
|
||||
|
||||
pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
||||
let engine_state = Rc::new(RefCell::new(EngineState::new()));
|
||||
@ -33,6 +35,8 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
||||
|
||||
working_set.add_decl(Box::new(Each));
|
||||
|
||||
working_set.add_decl(Box::new(Where));
|
||||
|
||||
working_set.add_decl(Box::new(Do));
|
||||
|
||||
working_set.add_decl(Box::new(Benchmark));
|
||||
|
@ -11,7 +11,7 @@ impl Command for If {
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Create a variable and give it a value."
|
||||
"Conditionally run a block."
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
|
@ -10,6 +10,7 @@ mod if_;
|
||||
mod length;
|
||||
mod let_;
|
||||
mod let_env;
|
||||
mod where_;
|
||||
|
||||
pub use alias::Alias;
|
||||
pub use benchmark::Benchmark;
|
||||
|
92
crates/nu-command/src/where_.rs
Normal file
92
crates/nu-command/src/where_.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::{Call, Expr, Expression};
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{IntoValueStream, ShellError, Signature, SyntaxShape, Value};
|
||||
|
||||
pub struct Where;
|
||||
|
||||
impl Command for Where {
|
||||
fn name(&self) -> &str {
|
||||
"where"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Filter values based on a condition."
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition")
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
call: &Call,
|
||||
input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let cond = call.positional[0].clone();
|
||||
|
||||
let context = context.enter_scope();
|
||||
|
||||
let (var_id, cond) = match cond {
|
||||
Expression {
|
||||
expr: Expr::RowCondition(var_id, expr),
|
||||
..
|
||||
} => (var_id, expr),
|
||||
_ => return Err(ShellError::InternalError("Expected row condition".into())),
|
||||
};
|
||||
|
||||
match input {
|
||||
Value::Stream { stream, span } => {
|
||||
let output_stream = stream
|
||||
.filter(move |value| {
|
||||
context.add_var(var_id, value.clone());
|
||||
|
||||
let result = eval_expression(&context, &cond);
|
||||
|
||||
match result {
|
||||
Ok(result) => result.is_true(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.into_value_stream();
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: output_stream,
|
||||
span,
|
||||
})
|
||||
}
|
||||
Value::List { vals, span } => {
|
||||
let output_stream = vals
|
||||
.into_iter()
|
||||
.filter(move |value| {
|
||||
context.add_var(var_id, value.clone());
|
||||
|
||||
let result = eval_expression(&context, &cond);
|
||||
|
||||
match result {
|
||||
Ok(result) => result.is_true(),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.into_value_stream();
|
||||
|
||||
Ok(Value::Stream {
|
||||
stream: output_stream,
|
||||
span,
|
||||
})
|
||||
}
|
||||
x => {
|
||||
context.add_var(var_id, x.clone());
|
||||
|
||||
let result = eval_expression(&context, &cond)?;
|
||||
|
||||
if result.is_true() {
|
||||
Ok(x)
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user