Improve dollar (#20672)

* Improve dollar for uri

* Refactor

* .

* .

* verde

* optimize

* https://github.com/nim-lang/Nim/pull/20672#issuecomment-1295440246 [skip ci]

* https://github.com/nim-lang/Nim/pull/20670#issuecomment-1295937393

* ci

* Update lib/pure/uri.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
Juan Carlos 2022-10-31 16:37:09 -03:00 • committed by GitHub
commit 2f6e06d224
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 31 deletions

View file

@ -113,6 +113,8 @@
- `random.rand` now works with `Ordinal`s. - `random.rand` now works with `Ordinal`s.
- Undeprecated `os.isvalidfilename`. - Undeprecated `os.isvalidfilename`.
- `std/oids` now uses `int64` to store time internally (before it was int32). - `std/oids` now uses `int64` to store time internally (before it was int32).
- `std/uri.Uri` dollar `$` improved, precalculates the `string` result length from the `Uri`.
[//]: # "Additions:" [//]: # "Additions:"
- Added ISO 8601 week date utilities in `times`: - Added ISO 8601 week date utilities in `times`:

View file

@ -494,42 +494,61 @@ func `$`*(u: Uri): string =
## Returns the string representation of the specified URI object. ## Returns the string representation of the specified URI object.
runnableExamples: runnableExamples:
assert $parseUri("https://nim-lang.org") == "https://nim-lang.org" assert $parseUri("https://nim-lang.org") == "https://nim-lang.org"
result = "" # Get the len of all the parts.
if u.scheme.len > 0: let schemeLen = u.scheme.len
result.add(u.scheme) let usernameLen = u.username.len
if u.opaque: let passwordLen = u.password.len
result.add(":") let hostnameLen = u.hostname.len
else: let portLen = u.port.len
result.add("://") let pathLen = u.path.len
if u.username.len > 0: let queryLen = u.query.len
result.add(u.username) let anchorLen = u.anchor.len
if u.password.len > 0: # Prepare a string that fits all the parts and all punctuation chars.
result.add(":") # 12 is the max len required by all possible punctuation chars.
result.add(u.password) result = newStringOfCap(
result.add("@") schemeLen + usernameLen + passwordLen + hostnameLen + portLen + pathLen + queryLen + anchorLen + 12
)
# Insert to result.
if schemeLen > 0:
result.add u.scheme
result.add ':'
if not u.opaque:
result.add '/'
result.add '/'
if usernameLen > 0:
result.add u.username
if passwordLen > 0:
result.add ':'
result.add u.password
result.add '@'
if u.hostname.endsWith('/'): if u.hostname.endsWith('/'):
if u.isIpv6: if u.isIpv6:
result.add("[" & u.hostname[0 .. ^2] & "]") result.add '['
result.add u.hostname[0 .. ^2]
result.add ']'
else: else:
result.add(u.hostname[0 .. ^2]) result.add u.hostname[0 .. ^2]
else: else:
if u.isIpv6: if u.isIpv6:
result.add("[" & u.hostname & "]") result.add '['
result.add u.hostname
result.add ']'
else: else:
result.add(u.hostname) result.add u.hostname
if u.port.len > 0: if portLen > 0:
result.add(":") result.add ':'
result.add(u.port) result.add u.port
if u.path.len > 0: if pathLen > 0:
if u.hostname.len > 0 and u.path[0] != '/': if hostnameLen > 0 and u.path[0] != '/':
result.add('/') result.add '/'
result.add(u.path) result.add u.path
if u.query.len > 0: if queryLen > 0:
result.add("?") result.add '?'
result.add(u.query) result.add u.query
if u.anchor.len > 0: if anchorLen > 0:
result.add("#") result.add '#'
result.add(u.anchor) result.add u.anchor
proc getDataUri*(data, mime: string, encoding = "utf-8"): string {.since: (1, 3).} = proc getDataUri*(data, mime: string, encoding = "utf-8"): string {.since: (1, 3).} =
## Convenience proc for `base64.encode` returns a standard Base64 Data URI (RFC-2397) ## Convenience proc for `base64.encode` returns a standard Base64 Data URI (RFC-2397)