mirror of
https://github.com/nushell/nushell.git
synced 2024-11-28 03:13:44 +01:00
Feature url build_query
accepts records with lists of strings (#14073)
<!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Swagger supports lists (a.k.a arrays) in query parameters: https://swagger.io/docs/specification/v3_0/serialization/ It supports three different styles: - explode=true - spaceDelimited - pipeDelimited With explode=true being the default and hence most common. It is the hardest to use inside of nushell, as the others are just a `string join` away. This commit adds lists with the explode=true format. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> Before: : {a[]: [one two three], b: four} | url build-query Error: nu:🐚:unsupported_input × Unsupported input ╭─[entry #33:1:1] 1 │ {a[]: [one two three], b: four} | url build-query · ───────────────┬─────────────── ───────┬─────── · │ ╰── Expected a record with string values · ╰── value originates from here ╰──── After: : {a[]: [one two three], b: four} | url build-query a%5B%5D=one&a%5B%5D=two&a%5B%5D=three&b=four Despite reading CONTRIBUTING.md I didn't get approval before making the change. My judgment is that this doesn't qualify as being "change something significantly". # Tests + Formatting I added the Example instance for the automatic tests. I couldn't figure out how to add an Example for the error case, so I did that with manual testing. E.g.: : {a[]: [one two [three]], b: four} | url build-query Error: nu:🐚:unsupported_input × Unsupported input ╭─[entry #3:1:1] 1 │ {a[]: [one two [three]], b: four} | url build-query · ────────────────┬──────────────── ───────┬─────── · │ ╰── Expected a record with list of string values · ╰── value originates from here ╰──── : {a[]: [one two 3hr], b: four} | url build-query Error: nu:🐚:unsupported_input × Unsupported input ╭─[entry #4:1:1] 1 │ {a[]: [one two 3hr], b: four} | url build-query · ──────────────┬────────────── ───────┬─────── · │ ╰── Expected a record with list of string values · ╰── value originates from here ╰──── <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> I ran the four cargo commands on my local machine. I had to run the tests with: LANG=C and -j 1 and even then I got one failure: thread 'commands::umkdir::mkdir_umask_permission' panicked at crates/nu-command/tests/commands/umkdir.rs:148:9: assertion `left == right` failed: Most *nix systems have 0o00022 as the umask. So directory permission should be 0o40755 = 0o 40777 & (!0o00022) left: 16893 right: 16877 but this isn't related to this change (I seem to not be running most *nix system; and don't have a lot of RAM for the number of cores). The other three cargo commands didn't have errors or warnings. # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> I will add the new example to [the documentation](https://github.com/nushell/nushell.github.io). # Open questions / possible future work Things I noticed, and would like to mention and am open to adding, but don't think I am deep enough in nushell to do them pro-actively. ## Add an argument for the other query parameter list styles I don't know how frequent they are and I currently don't need them, so following KISS I didn't add them. ## long input_span marked In e.g.: : {a[]: [one two 3hr], b: four} | url build-query Error: nu:🐚:unsupported_input × Unsupported input ╭─[entry #4:1:1] 1 │ {a[]: [one two 3hr], b: four} | url build-query · ──────────────┬────────────── ───────┬─────── · │ ╰── Expected a record with list of string values · ╰── value originates from here ╰──── the entire record is marked as input_span instead of just the "3hr" that is causing the problem. Changing that would be trivial, but I'm not deep enough into nushell to understand all the consequences of changing that. ## Error message says string values despite accepting numbers etc. The error message said it only accepted strings despite accepting numbers etc. (anything it can coerce into string). I couldn't find a good wording myself and that was how it was before. I simply added a "list of strings".
This commit is contained in:
parent
f3a1dfef95
commit
04fed82e5e
@ -42,6 +42,11 @@ impl Command for SubCommand {
|
||||
example: r#"{a:"AT&T", b: "AT T"} | url build-query"#,
|
||||
result: Some(Value::test_string("a=AT%26T&b=AT+T")),
|
||||
},
|
||||
Example {
|
||||
description: "Outputs a query string representing the contents of this record",
|
||||
example: r#"{a: ["one", "two"], b: "three"} | url build-query"#,
|
||||
result: Some(Value::test_string("a=one&a=two&b=three")),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@ -66,30 +71,44 @@ fn to_url(input: PipelineData, head: Span) -> Result<PipelineData, ShellError> {
|
||||
Value::Record { ref val, .. } => {
|
||||
let mut row_vec = vec![];
|
||||
for (k, v) in &**val {
|
||||
match v.coerce_string() {
|
||||
Ok(s) => {
|
||||
row_vec.push((k.clone(), s));
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::UnsupportedInput {
|
||||
msg: "Expected a record with string values".to_string(),
|
||||
input: "value originates from here".into(),
|
||||
msg_span: head,
|
||||
input_span: span,
|
||||
});
|
||||
match v {
|
||||
Value::List { ref vals, .. } => {
|
||||
for v_item in vals {
|
||||
row_vec.push((
|
||||
k.clone(),
|
||||
v_item.coerce_string().map_err(|_| {
|
||||
ShellError::UnsupportedInput {
|
||||
msg: "Expected a record with list of string values"
|
||||
.to_string(),
|
||||
input: "value originates from here".into(),
|
||||
msg_span: head,
|
||||
input_span: span,
|
||||
}
|
||||
})?,
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => row_vec.push((
|
||||
k.clone(),
|
||||
v.coerce_string()
|
||||
.map_err(|_| ShellError::UnsupportedInput {
|
||||
msg:
|
||||
"Expected a record with string or list of string values"
|
||||
.to_string(),
|
||||
input: "value originates from here".into(),
|
||||
msg_span: head,
|
||||
input_span: span,
|
||||
})?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
match serde_urlencoded::to_string(row_vec) {
|
||||
Ok(s) => Ok(s),
|
||||
_ => Err(ShellError::CantConvert {
|
||||
to_type: "URL".into(),
|
||||
from_type: value.get_type().to_string(),
|
||||
span: head,
|
||||
help: None,
|
||||
}),
|
||||
}
|
||||
serde_urlencoded::to_string(row_vec).map_err(|_| ShellError::CantConvert {
|
||||
to_type: "URL".into(),
|
||||
from_type: value.get_type().to_string(),
|
||||
span: head,
|
||||
help: None,
|
||||
})
|
||||
}
|
||||
// Propagate existing errors
|
||||
Value::Error { error, .. } => Err(*error),
|
||||
|
Loading…
Reference in New Issue
Block a user