mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
Merge pull request #10513 from LemonBoy/uri-encq
Add `encodeQuery` and `?` to Uri module
This commit is contained in:
@@ -119,6 +119,33 @@ proc decodeUrl*(s: string, decodePlus=true): string =
|
||||
inc(j)
|
||||
setLen(result, j)
|
||||
|
||||
proc encodeQuery*(query: openArray[(string, string)], usePlus=true, omitEq=true): string =
|
||||
## Encodes a set of (key, value) parameters into a URL query string.
|
||||
##
|
||||
## Every (key, value) pair is URL-encoded and written as ``key=value``. If the
|
||||
## value is an empty string then the ``=`` is omitted, unless ``omitEq`` is
|
||||
## false.
|
||||
## The pairs are joined together by a ``&`` character.
|
||||
##
|
||||
## The ``usePlus`` parameter is passed down to the `encodeUrl` function that
|
||||
## is used for the URL encoding of the string values.
|
||||
##
|
||||
## **See also:**
|
||||
## * `encodeUrl proc<#encodeUrl,string>`_
|
||||
runnableExamples:
|
||||
assert encodeQuery({:}) == ""
|
||||
assert encodeQuery({"a": "1", "b": "2"}) == "a=1&b=2"
|
||||
assert encodeQuery({"a": "1", "b": ""}) == "a=1&b"
|
||||
for elem in query:
|
||||
# Encode the `key = value` pairs and separate them with a '&'
|
||||
if result.len > 0: result.add('&')
|
||||
let (key, val) = elem
|
||||
result.add(encodeUrl(key, usePlus))
|
||||
# Omit the '=' if the value string is empty
|
||||
if not omitEq or val.len > 0:
|
||||
result.add('=')
|
||||
result.add(encodeUrl(val, usePlus))
|
||||
|
||||
proc parseAuthority(authority: string, result: var Uri) =
|
||||
var i = 0
|
||||
var inPort = false
|
||||
@@ -392,6 +419,14 @@ proc `/`*(x: Uri, path: string): Uri =
|
||||
result.path.add '/'
|
||||
result.path.add(path)
|
||||
|
||||
proc `?`*(u: Uri, query: openArray[(string, string)]): Uri =
|
||||
## Concatenates the query parameters to the specified URI object.
|
||||
runnableExamples:
|
||||
let foo = parseUri("https://example.com") / "foo" ? {"bar": "qux"}
|
||||
assert $foo == "https://example.com/foo?bar=qux"
|
||||
result = u
|
||||
result.query = encodeQuery(query)
|
||||
|
||||
proc `$`*(u: Uri): string =
|
||||
## Returns the string representation of the specified URI object.
|
||||
runnableExamples:
|
||||
@@ -676,4 +711,25 @@ when isMainModule:
|
||||
doAssert "https://example.com/about/staff.html?".parseUri().isAbsolute == true
|
||||
doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true
|
||||
|
||||
# encodeQuery tests
|
||||
block:
|
||||
doAssert encodeQuery({:}) == ""
|
||||
doAssert encodeQuery({"foo": "bar"}) == "foo=bar"
|
||||
doAssert encodeQuery({"foo": "bar & baz"}) == "foo=bar+%26+baz"
|
||||
doAssert encodeQuery({"foo": "bar & baz"}, usePlus=false) == "foo=bar%20%26%20baz"
|
||||
doAssert encodeQuery({"foo": ""}) == "foo"
|
||||
doAssert encodeQuery({"foo": ""}, omitEq=false) == "foo="
|
||||
doAssert encodeQuery({"a": "1", "b": "", "c": "3"}) == "a=1&b&c=3"
|
||||
doAssert encodeQuery({"a": "1", "b": "", "c": "3"}, omitEq=false) == "a=1&b=&c=3"
|
||||
|
||||
block:
|
||||
var foo = parseUri("http://example.com") / "foo" ? {"bar": "1", "baz": "qux"}
|
||||
var foo1 = parseUri("http://example.com/foo?bar=1&baz=qux")
|
||||
doAssert foo == foo1
|
||||
|
||||
block:
|
||||
var foo = parseUri("http://example.com") / "foo" ? {"do": "do", "bar": ""}
|
||||
var foo1 = parseUri("http://example.com/foo?do=do&bar")
|
||||
doAssert foo == foo1
|
||||
|
||||
echo("All good!")
|
||||
|
||||
Reference in New Issue
Block a user