nu_command/filters/
empty.rs

1use nu_engine::command_prelude::*;
2use nu_protocol::shell_error::io::IoError;
3use std::io::Read;
4
5pub fn empty(
6    engine_state: &EngineState,
7    stack: &mut Stack,
8    call: &Call,
9    input: PipelineData,
10    negate: bool,
11) -> Result<PipelineData, ShellError> {
12    let head = call.head;
13    let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
14
15    if !columns.is_empty() {
16        for val in input {
17            for column in &columns {
18                if !val.follow_cell_path(&column.members)?.is_nothing() {
19                    return Ok(Value::bool(negate, head).into_pipeline_data());
20                }
21            }
22        }
23
24        if negate {
25            Ok(Value::bool(false, head).into_pipeline_data())
26        } else {
27            Ok(Value::bool(true, head).into_pipeline_data())
28        }
29    } else {
30        match input {
31            PipelineData::Empty => Ok(PipelineData::empty()),
32            PipelineData::ByteStream(stream, ..) => {
33                let span = stream.span();
34                match stream.reader() {
35                    Some(reader) => {
36                        let is_empty = reader
37                            .bytes()
38                            .next()
39                            .transpose()
40                            .map_err(|err| IoError::new(err, span, None))?
41                            .is_none();
42                        if negate {
43                            Ok(Value::bool(!is_empty, head).into_pipeline_data())
44                        } else {
45                            Ok(Value::bool(is_empty, head).into_pipeline_data())
46                        }
47                    }
48                    None => {
49                        if negate {
50                            Ok(Value::bool(false, head).into_pipeline_data())
51                        } else {
52                            Ok(Value::bool(true, head).into_pipeline_data())
53                        }
54                    }
55                }
56            }
57            PipelineData::ListStream(s, ..) => {
58                let empty = s.into_iter().next().is_none();
59                if negate {
60                    Ok(Value::bool(!empty, head).into_pipeline_data())
61                } else {
62                    Ok(Value::bool(empty, head).into_pipeline_data())
63                }
64            }
65            PipelineData::Value(value, ..) => {
66                if negate {
67                    Ok(Value::bool(!value.is_empty(), head).into_pipeline_data())
68                } else {
69                    Ok(Value::bool(value.is_empty(), head).into_pipeline_data())
70                }
71            }
72        }
73    }
74}