mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-14 15:43:45 +00:00
fix(uri): ? operator now appends to existing query string (#25831)
## Summary Fixes #19782. The `?` operator in `std/uri` was silently overwriting any query string already present in the URI. This PR makes it append instead — which matches the docstring ("Concatenates the query parameters") and the natural expectation when chaining operations. **Before:** ```nim let u = parseUri("https://example.com/foo?existing=1") ? {"bar": "qux"} echo $u # https://example.com/foo?bar=qux (existing=1 lost) ``` **After:** ```nim let u = parseUri("https://example.com/foo?existing=1") ? {"bar": "qux"} echo $u # https://example.com/foo?existing=1&bar=qux ``` ## Changes - `lib/pure/uri.nim`: fix `?` to append with `&` when a query string already exists; add example to `runnableExamples` - `tests/stdlib/turi.nim`: two new test cases (append to existing query, empty params preserve existing) - `changelog.md`: entry under Standard library changes ## Notes I work with Claude as a co-processor. I'm 56, came to programming late, and this is genuinely how I learn and contribute. I understand what I'm submitting, but I didn't write it alone. If your project prefers human-only contributions, just say so and I'll close without friction. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: n0madgang <14005836+n0madgang@users.noreply.github.com>
This commit is contained in:
@@ -84,6 +84,8 @@ parameter and result types, not just their source-level shape. Use
|
||||
- `std/pegs` now correctly lexes UTF-8 bytes inside bare identifier-style
|
||||
terminals, so case-insensitive matching of non-ASCII terms (e.g. ``\i café``)
|
||||
works without single-quoting.
|
||||
- `std/uri`: The `?` operator now appends query parameters to an existing query
|
||||
string instead of replacing it. Fixes [#19782](https://github.com/nim-lang/Nim/issues/19782).
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
@@ -487,11 +487,18 @@ func `/`*(x: Uri, path: string): Uri =
|
||||
|
||||
func `?`*(u: Uri, query: openArray[(string, string)]): Uri =
|
||||
## Concatenates the query parameters to the specified URI object.
|
||||
## If the URI already has a query string, the new parameters are appended.
|
||||
runnableExamples:
|
||||
let foo = parseUri("https://example.com") / "foo" ? {"bar": "qux"}
|
||||
assert $foo == "https://example.com/foo?bar=qux"
|
||||
let bar = parseUri("https://example.com/foo?existing=1") ? {"bar": "qux"}
|
||||
assert $bar == "https://example.com/foo?existing=1&bar=qux"
|
||||
result = u
|
||||
result.query = encodeQuery(query)
|
||||
let newQuery = encodeQuery(query)
|
||||
if newQuery.len > 0:
|
||||
if result.query.len > 0:
|
||||
result.query.add('&')
|
||||
result.query.add(newQuery)
|
||||
|
||||
func `$`*(u: Uri): string =
|
||||
## Returns the string representation of the specified URI object.
|
||||
|
||||
@@ -289,6 +289,15 @@ template main() =
|
||||
var foo = parseUri("http://example.com") / "foo" ? {"do": "do", "bar": ""}
|
||||
var foo1 = parseUri("http://example.com/foo?do=do&bar")
|
||||
doAssert foo == foo1
|
||||
block: # issue #19782: appends to existing query string
|
||||
var foo = parseUri("http://example.com/foo?existing=1") ? {"bar": "qux"}
|
||||
doAssert $foo == "http://example.com/foo?existing=1&bar=qux"
|
||||
block: # issue #19782: empty params list preserves existing query
|
||||
var foo = parseUri("http://example.com/foo?existing=1") ? {:}
|
||||
doAssert $foo == "http://example.com/foo?existing=1"
|
||||
block: # issue #19782: empty params on uri without query is a no-op
|
||||
var foo = parseUri("http://example.com/foo") ? {:}
|
||||
doAssert $foo == "http://example.com/foo"
|
||||
|
||||
block: # getDataUri, dataUriBase64
|
||||
doAssert getDataUri("", "text/plain") == "data:text/plain;charset=utf-8;base64,"
|
||||
|
||||
Reference in New Issue
Block a user