Url split query (#14211)

Addresses the following points from #14162

> - There is no built-in counterpart to url build-query for splitting a
query string

There is `from url`, which, due to naming, is a little hard to discover
and suffers from the following point

> - url parse can create records with duplicate keys
> - url parse's params should either:
>   - ~group the same keys into a list.~
> - instead of a record, be a key-value table. (table<key: string,
value: string>)

# Description

## `url split-query`

Counterpart to `url build-query`, splits a url encoded query string to
key value pairs, represented as `table<key: string, value: string>`

```
> "a=one&a=two&b=three" | url split-query
╭───┬─────┬───────╮
│ # │ key │ value │
├───┼─────┼───────┤
│ 0 │ a   │ one   │
│ 1 │ a   │ two   │
│ 2 │ b   │ three │
╰───┴─────┴───────╯
```

## `url parse`

The output's `param` field is now a table as well, mirroring the new
`url split-query`

```
> 'http://localhost?a=one&a=two&b=three' | url parse
╭──────────┬─────────────────────╮
│ scheme   │ http                │
│ username │                     │
│ password │                     │
│ host     │ localhost           │
│ port     │                     │
│ path     │ /                   │
│ query    │ a=one&a=two&b=three │
│ fragment │                     │
│          │ ╭───┬─────┬───────╮ │
│ params   │ │ # │ key │ value │ │
│          │ ├───┼─────┼───────┤ │
│          │ │ 0 │ a   │ one   │ │
│          │ │ 1 │ a   │ two   │ │
│          │ │ 2 │ b   │ three │ │
│          │ ╰───┴─────┴───────╯ │
╰──────────┴─────────────────────╯
```

# User-Facing Changes

- `url parse`'s output has the mentioned change, which is backwards
incompatible.
This commit is contained in:
Bahex
2024-11-06 16:35:37 +03:00
committed by GitHub
parent d52ec65f18
commit 3182adb6a0
6 changed files with 200 additions and 55 deletions

View File

@ -15,7 +15,7 @@ fn url_parse_simple() {
path: '/',
query: '',
fragment: '',
params: {}
params: []
}
"#
));
@ -37,7 +37,7 @@ fn url_parse_with_port() {
path: '/',
query: '',
fragment: '',
params: {}
params: []
}
"#
));
@ -60,7 +60,7 @@ fn url_parse_with_path() {
path: '/def/ghj',
query: '',
fragment: '',
params: {}
params: []
}
"#
));
@ -83,7 +83,30 @@ fn url_parse_with_params() {
path: '/def/ghj',
query: 'param1=11&param2=',
fragment: '',
params: {param1: '11', param2: ''}
params: [[key, value]; ["param1", "11"], ["param2", ""]]
}
"#
));
assert_eq!(actual.out, "true");
}
#[test]
fn url_parse_with_duplicate_params() {
let actual = nu!(pipeline(
r#"
("http://www.abc.com:8811/def/ghj?param1=11&param2=&param1=22"
| url parse)
== {
scheme: 'http',
username: '',
password: '',
host: 'www.abc.com',
port: '8811',
path: '/def/ghj',
query: 'param1=11&param2=&param1=22',
fragment: '',
params: [[key, value]; ["param1", "11"], ["param2", ""], ["param1", "22"]]
}
"#
));
@ -106,7 +129,7 @@ fn url_parse_with_fragment() {
path: '/def/ghj',
query: 'param1=11&param2=',
fragment: 'hello-fragment',
params: {param1: '11', param2: ''}
params: [[key, value]; ["param1", "11"], ["param2", ""]]
}
"#
));
@ -129,7 +152,7 @@ fn url_parse_with_username_and_password() {
path: '/def/ghj',
query: 'param1=11&param2=',
fragment: 'hello-fragment',
params: {param1: '11', param2: ''}
params: [[key, value]; ["param1", "11"], ["param2", ""]]
}
"#
));