nu_command/filters/
append.rs

1use nu_engine::command_prelude::*;
2
3#[derive(Clone)]
4pub struct Append;
5
6impl Command for Append {
7    fn name(&self) -> &str {
8        "append"
9    }
10
11    fn signature(&self) -> nu_protocol::Signature {
12        Signature::build("append")
13            .input_output_types(vec![(Type::Any, Type::List(Box::new(Type::Any)))])
14            .required(
15                "row",
16                SyntaxShape::Any,
17                "The row, list, or table to append.",
18            )
19            .allow_variants_without_examples(true)
20            .category(Category::Filters)
21    }
22
23    fn description(&self) -> &str {
24        "Append any number of rows to a table."
25    }
26
27    fn extra_description(&self) -> &str {
28        r#"Be aware that this command 'unwraps' lists passed to it. So, if you pass a variable to it,
29and you want the variable's contents to be appended without being unwrapped, it's wise to
30pre-emptively wrap the variable in a list, like so: `append [$val]`. This way, `append` will
31only unwrap the outer list, and leave the variable's contents untouched."#
32    }
33
34    fn search_terms(&self) -> Vec<&str> {
35        vec!["add", "concatenate"]
36    }
37
38    fn examples(&self) -> Vec<Example> {
39        vec![
40            Example {
41                example: "[0 1 2 3] | append 4",
42                description: "Append one int to a list",
43                result: Some(Value::test_list(vec![
44                    Value::test_int(0),
45                    Value::test_int(1),
46                    Value::test_int(2),
47                    Value::test_int(3),
48                    Value::test_int(4),
49                ])),
50            },
51            Example {
52                example: "0 | append [1 2 3]",
53                description: "Append a list to an item",
54                result: Some(Value::test_list(vec![
55                    Value::test_int(0),
56                    Value::test_int(1),
57                    Value::test_int(2),
58                    Value::test_int(3),
59                ])),
60            },
61            Example {
62                example: r#""a" | append ["b"] "#,
63                description: "Append a list of string to a string",
64                result: Some(Value::test_list(vec![
65                    Value::test_string("a"),
66                    Value::test_string("b"),
67                ])),
68            },
69            Example {
70                example: "[0 1] | append [2 3 4]",
71                description: "Append three int items",
72                result: Some(Value::test_list(vec![
73                    Value::test_int(0),
74                    Value::test_int(1),
75                    Value::test_int(2),
76                    Value::test_int(3),
77                    Value::test_int(4),
78                ])),
79            },
80            Example {
81                example: "[0 1] | append [2 nu 4 shell]",
82                description: "Append ints and strings",
83                result: Some(Value::test_list(vec![
84                    Value::test_int(0),
85                    Value::test_int(1),
86                    Value::test_int(2),
87                    Value::test_string("nu"),
88                    Value::test_int(4),
89                    Value::test_string("shell"),
90                ])),
91            },
92            Example {
93                example: "[0 1] | append 2..4",
94                description: "Append a range of ints to a list",
95                result: Some(Value::test_list(vec![
96                    Value::test_int(0),
97                    Value::test_int(1),
98                    Value::test_int(2),
99                    Value::test_int(3),
100                    Value::test_int(4),
101                ])),
102            },
103        ]
104    }
105
106    fn run(
107        &self,
108        engine_state: &EngineState,
109        stack: &mut Stack,
110        call: &Call,
111        input: PipelineData,
112    ) -> Result<PipelineData, ShellError> {
113        let other: Value = call.req(engine_state, stack, 0)?;
114        let metadata = input.metadata();
115
116        Ok(input
117            .into_iter()
118            .chain(other.into_pipeline_data())
119            .into_pipeline_data_with_metadata(call.head, engine_state.signals().clone(), metadata))
120    }
121}
122
123#[cfg(test)]
124mod test {
125    use super::*;
126
127    #[test]
128    fn test_examples() {
129        use crate::test_examples;
130
131        test_examples(Append {})
132    }
133}