nu_command/filters/
utils.rs

1use nu_engine::{CallExt, ClosureEval};
2use nu_protocol::{
3    IntoPipelineData, PipelineData, ShellError, Span, Value,
4    engine::{Call, Closure, EngineState, Stack},
5};
6
7pub fn chain_error_with_input(
8    error_source: ShellError,
9    input_is_error: bool,
10    span: Span,
11) -> ShellError {
12    if !input_is_error {
13        return ShellError::EvalBlockWithInput {
14            span,
15            sources: vec![error_source],
16        };
17    }
18    error_source
19}
20
21pub fn boolean_fold(
22    engine_state: &EngineState,
23    stack: &mut Stack,
24    call: &Call,
25    input: PipelineData,
26    accumulator: bool,
27) -> Result<PipelineData, ShellError> {
28    let head = call.head;
29    let closure: Closure = call.req(engine_state, stack, 0)?;
30
31    let mut closure = ClosureEval::new(engine_state, stack, closure);
32
33    for value in input {
34        engine_state.signals().check(&head)?;
35        let pred = closure.run_with_value(value)?.into_value(head)?.is_true();
36
37        if pred == accumulator {
38            return Ok(Value::bool(accumulator, head).into_pipeline_data());
39        }
40    }
41
42    Ok(Value::bool(!accumulator, head).into_pipeline_data())
43}