Skip to main content

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