nu_command/network/url/
split_query.rs

1use nu_engine::command_prelude::*;
2
3use super::query::query_string_to_table;
4
5#[derive(Clone)]
6pub struct UrlSplitQuery;
7
8impl Command for UrlSplitQuery {
9    fn name(&self) -> &str {
10        "url split-query"
11    }
12
13    fn signature(&self) -> Signature {
14        Signature::build("url split-query")
15            .input_output_types(vec![(
16                Type::String,
17                Type::Table([("key".into(), Type::String), ("value".into(), Type::String)].into()),
18            )])
19            .category(Category::Network)
20    }
21
22    fn description(&self) -> &str {
23        "Converts query string into table applying percent-decoding."
24    }
25
26    fn search_terms(&self) -> Vec<&str> {
27        vec!["convert", "record", "table"]
28    }
29
30    fn examples(&self) -> Vec<Example<'_>> {
31        vec![
32            Example {
33                description: "Outputs a table representing the contents of this query string",
34                example: r#""mode=normal&userid=31415" | url split-query"#,
35                result: Some(Value::test_list(vec![
36                    Value::test_record(record! {
37                        "key" => Value::test_string("mode"),
38                        "value" => Value::test_string("normal"),
39                    }),
40                    Value::test_record(record! {
41                        "key" => Value::test_string("userid"),
42                        "value" => Value::test_string("31415"),
43                    }),
44                ])),
45            },
46            Example {
47                description: "Outputs a table representing the contents of this query string, url-decoding the values",
48                example: r#""a=AT%26T&b=AT+T" | url split-query"#,
49                result: Some(Value::test_list(vec![
50                    Value::test_record(record! {
51                        "key" => Value::test_string("a"),
52                        "value" => Value::test_string("AT&T"),
53                    }),
54                    Value::test_record(record! {
55                        "key" => Value::test_string("b"),
56                        "value" => Value::test_string("AT T"),
57                    }),
58                ])),
59            },
60            Example {
61                description: "Outputs a table representing the contents of this query string",
62                example: r#""a=one&a=two&b=three" | url split-query"#,
63                result: Some(Value::test_list(vec![
64                    Value::test_record(record! {
65                        "key" => Value::test_string("a"),
66                        "value" => Value::test_string("one"),
67                    }),
68                    Value::test_record(record! {
69                        "key" => Value::test_string("a"),
70                        "value" => Value::test_string("two"),
71                    }),
72                    Value::test_record(record! {
73                        "key" => Value::test_string("b"),
74                        "value" => Value::test_string("three"),
75                    }),
76                ])),
77            },
78        ]
79    }
80
81    fn run(
82        &self,
83        engine_state: &EngineState,
84        stack: &mut Stack,
85        call: &Call,
86        input: PipelineData,
87    ) -> Result<PipelineData, ShellError> {
88        let value = input.into_value(call.head)?;
89        let span = value.span();
90        let query = value.to_expanded_string("", &stack.get_config(engine_state));
91        let table = query_string_to_table(&query, call.head, span)?;
92        Ok(PipelineData::value(table, None))
93    }
94}
95
96#[cfg(test)]
97mod test {
98    use super::*;
99
100    #[test]
101    fn test_examples() {
102        use crate::test_examples;
103
104        test_examples(UrlSplitQuery {})
105    }
106}