nu_command/filters/
every.rs1use nu_engine::command_prelude::*;
2
3#[derive(Clone)]
4pub struct Every;
5
6impl Command for Every {
7 fn name(&self) -> &str {
8 "every"
9 }
10
11 fn signature(&self) -> Signature {
12 Signature::build("every")
13 .input_output_types(vec![(
14 Type::List(Box::new(Type::Any)),
15 Type::List(Box::new(Type::Any)),
16 )])
17 .required(
18 "stride",
19 SyntaxShape::Int,
20 "How many rows to skip between (and including) each row returned.",
21 )
22 .switch(
23 "skip",
24 "skip the rows that would be returned, instead of selecting them",
25 Some('s'),
26 )
27 .category(Category::Filters)
28 }
29
30 fn description(&self) -> &str {
31 "Show (or skip) every n-th row, starting from the first one."
32 }
33
34 fn examples(&self) -> Vec<Example<'_>> {
35 vec![
36 Example {
37 example: "[1 2 3 4 5] | every 2",
38 description: "Get every second row",
39 result: Some(Value::list(
40 vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)],
41 Span::test_data(),
42 )),
43 },
44 Example {
45 example: "[1 2 3 4 5] | every 2 --skip",
46 description: "Skip every second row",
47 result: Some(Value::list(
48 vec![Value::test_int(2), Value::test_int(4)],
49 Span::test_data(),
50 )),
51 },
52 ]
53 }
54
55 fn run(
56 &self,
57 engine_state: &EngineState,
58 stack: &mut Stack,
59 call: &Call,
60 input: PipelineData,
61 ) -> Result<PipelineData, ShellError> {
62 let stride = match call.req::<usize>(engine_state, stack, 0)? {
63 0 => 1,
64 stride => stride,
65 };
66
67 let skip = call.has_flag(engine_state, stack, "skip")?;
68
69 let metadata = input.metadata();
70
71 Ok(input
72 .into_iter()
73 .enumerate()
74 .filter_map(move |(i, value)| {
75 if (i % stride != 0) == skip {
76 Some(value)
77 } else {
78 None
79 }
80 })
81 .into_pipeline_data_with_metadata(call.head, engine_state.signals().clone(), metadata))
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88
89 #[test]
90 fn test_examples() {
91 use crate::test_examples;
92
93 test_examples(Every {})
94 }
95}