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