summary refs log tree commit diff stats
path: root/lib/pure/uri.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/uri.nim')
-rw-r--r--lib/pure/uri.nim174
1 files changed, 112 insertions, 62 deletions
diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim
index d296017dd..bfb411fc8 100644
--- a/lib/pure/uri.nim
+++ b/lib/pure/uri.nim
@@ -8,6 +8,35 @@
 #
 
 ## This module implements URI parsing as specified by RFC 3986.
+##
+## A Uniform Resource Identifier (URI) provides a simple and extensible
+## means for identifying a resource. A URI can be further classified
+## as a locator, a name, or both. The term “Uniform Resource Locator”
+## (URL) refers to the subset of URIs.
+##
+## Basic usage
+## ===========
+##
+## Combine URIs
+## -------------
+## .. code-block::
+##    import uri
+##    let host = parseUri("https://nim-lang.org")
+##    let blog = "/blog.html"
+##    let bloguri = host / blog
+##    assert $host == "https://nim-lang.org"
+##    assert $bloguri == "https://nim-lang.org/blog.html"
+##
+## Access URI item
+## ---------------
+## .. code-block::
+##    import uri
+##    let res = parseUri("sftp://127.0.0.1:4343")
+##    if isAbsolute(res):
+##      echo "Connect to port: " & res.port
+##      # --> Connect to port: 4343
+##    else:
+##      echo "Wrong format"
 
 import strutils, parseutils
 type
@@ -18,44 +47,24 @@ type
     hostname*, port*, path*, query*, anchor*: string
     opaque*: bool
 
-{.push warning[deprecated]: off.}
-proc `$`*(url: Url): string {.deprecated: "use Uri instead".} =
-  ## **Deprecated since 0.9.6**: Use ``Uri`` instead.
-  return string(url)
-
-proc `/`*(a, b: Url): Url {.deprecated: "use Uri instead".} =
-  ## Joins two URLs together, separating them with / if needed.
-  ##
-  ## **Deprecated since 0.9.6**: Use ``Uri`` instead.
-  var urlS = $a
-  var bS = $b
-  if urlS == "": return b
-  if urlS[urlS.len-1] != '/':
-    urlS.add('/')
-  if bS[0] == '/':
-    urlS.add(bS.substr(1))
-  else:
-    urlS.add(bs)
-  result = Url(urlS)
-
-proc add*(url: var Url, a: Url) {.deprecated: "use Uri instead".} =
-  ## Appends url to url.
-  ##
-  ## **Deprecated since 0.9.6**: Use ``Uri`` instead.
-  url = url / a
-{.pop.}
-
 proc encodeUrl*(s: string, usePlus=true): string =
   ## Encodes a URL according to RFC3986.
   ##
   ## This means that characters in the set
   ## ``{'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~'}`` are
   ## carried over to the result.
-  ## All other characters are encoded as ``''%xx'`` where ``xx``
+  ## All other characters are encoded as ``%xx`` where ``xx``
   ## denotes its hexadecimal value.
   ##
   ## As a special rule, when the value of ``usePlus`` is true,
-  ## spaces are encoded as ``'+'`` instead of ``'%20'``.
+  ## spaces are encoded as ``+`` instead of ``%20``.
+  ##
+  ## **See also:**
+  ## * `decodeUrl proc<#decodeUrl,string>`_
+  runnableExamples:
+    assert encodeUrl("https://nim-lang.org") == "https%3A%2F%2Fnim-lang.org"
+    assert encodeUrl("https://nim-lang.org/this is a test") == "https%3A%2F%2Fnim-lang.org%2Fthis+is+a+test"
+    assert encodeUrl("https://nim-lang.org/this is a test", false) == "https%3A%2F%2Fnim-lang.org%2Fthis%20is%20a%20test"
   result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars
   let fromSpace = if usePlus: "+" else: "%20"
   for c in s:
@@ -70,12 +79,19 @@ proc encodeUrl*(s: string, usePlus=true): string =
 proc decodeUrl*(s: string, decodePlus=true): string =
   ## Decodes a URL according to RFC3986.
   ##
-  ## This means that any ``'%xx'`` (where ``xx`` denotes a hexadecimal
+  ## This means that any ``%xx`` (where ``xx`` denotes a hexadecimal
   ## value) are converted to the character with ordinal number ``xx``,
   ## and every other character is carried over.
   ##
-  ## As a special rule, when the value of ``decodePlus`` is true, ``'+'``
+  ## As a special rule, when the value of ``decodePlus`` is true, ``+``
   ## characters are converted to a space.
+  ##
+  ## **See also:**
+  ## * `encodeUrl proc<#encodeUrl,string>`_
+  runnableExamples:
+    assert decodeUrl("https%3A%2F%2Fnim-lang.org") == "https://nim-lang.org"
+    assert decodeUrl("https%3A%2F%2Fnim-lang.org%2Fthis+is+a+test") == "https://nim-lang.org/this is a test"
+    assert decodeUrl("https%3A%2F%2Fnim-lang.org%2Fthis%20is%20a%20test", false) == "https://nim-lang.org/this is a test"
   proc handleHexChar(c: char, x: var int) {.inline.} =
     case c
     of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
@@ -150,7 +166,14 @@ proc parsePath(uri: string, i: var int, result: var Uri) =
     i.inc parseUntil(uri, result.anchor, {}, i)
 
 proc initUri*(): Uri =
-  ## Initializes a URI.
+  ## Initializes a URI with ``scheme``, ``username``, ``password``,
+  ## ``hostname``, ``port``, ``path``, ``query`` and ``anchor``.
+  ##
+  ## **See also:**
+  ## * `Uri type <#Uri>`_ for available fields in the URI type
+  runnableExamples:
+    var uri: Uri
+    assert initUri() == uri
   result = Uri(scheme: "", username: "", password: "", hostname: "", port: "",
                 path: "", query: "", anchor: "")
 
@@ -163,6 +186,16 @@ proc resetUri(uri: var Uri) =
 
 proc parseUri*(uri: string, result: var Uri) =
   ## Parses a URI. The `result` variable will be cleared before.
+  ##
+  ## **See also:**
+  ## * `Uri type <#Uri>`_ for available fields in the URI type
+  ## * `initUri proc <#initUri,>`_ for initializing a URI
+  runnableExamples:
+    var res = initUri()
+    parseUri("https://nim-lang.org/docs/manual.html", res)
+    assert res.scheme == "https"
+    assert res.hostname == "nim-lang.org"
+    assert res.path == "/docs/manual.html"
   resetUri(result)
 
   var i = 0
@@ -201,6 +234,14 @@ proc parseUri*(uri: string, result: var Uri) =
 
 proc parseUri*(uri: string): Uri =
   ## Parses a URI and returns it.
+  ##
+  ## **See also:**
+  ## * `Uri type <#Uri>`_ for available fields in the URI type
+  runnableExamples:
+    let res = parseUri("ftp://Username:Password@Hostname")
+    assert res.username == "Username"
+    assert res.password == "Password"
+    assert res.scheme == "ftp"
   result = initUri()
   parseUri(uri, result)
 
@@ -251,22 +292,18 @@ proc combine*(base: Uri, reference: Uri): Uri =
   ## This uses the algorithm specified in
   ## `section 5.2.2 of RFC 3986 <http://tools.ietf.org/html/rfc3986#section-5.2.2>`_.
   ##
-  ## This means that the slashes inside the base URI's path as well as reference
-  ## URI's path affect the resulting URI.
-  ##
-  ## For building URIs you may wish to use \`/\` instead.
-  ##
-  ## Examples:
-  ##
-  ## .. code-block::
-  ##   let foo = combine(parseUri("http://example.com/foo/bar"), parseUri("/baz"))
-  ##   assert foo.path == "/baz"
-  ##
-  ##   let bar = combine(parseUri("http://example.com/foo/bar"), parseUri("baz"))
-  ##   assert bar.path == "/foo/baz"
+  ## This means that the slashes inside the base URIs path as well as reference
+  ## URIs path affect the resulting URI.
   ##
-  ##   let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz"))
-  ##   assert bar.path == "/foo/bar/baz"
+  ## **See also:**
+  ## * `/ proc <#/,Uri,string>`_ for building URIs
+  runnableExamples:
+    let foo = combine(parseUri("https://nim-lang.org/foo/bar"), parseUri("/baz"))
+    assert foo.path == "/baz"
+    let bar = combine(parseUri("https://nim-lang.org/foo/bar"), parseUri("baz"))
+    assert bar.path == "/foo/baz"
+    let qux = combine(parseUri("https://nim-lang.org/foo/bar/"), parseUri("baz"))
+    assert qux.path == "/foo/bar/baz"
 
   template setAuthority(dest, src): untyped =
     dest.hostname = src.hostname
@@ -302,32 +339,42 @@ proc combine*(base: Uri, reference: Uri): Uri =
 
 proc combine*(uris: varargs[Uri]): Uri =
   ## Combines multiple URIs together.
+  ##
+  ## **See also:**
+  ## * `/ proc <#/,Uri,string>`_ for building URIs
+  runnableExamples:
+    let foo = combine(parseUri("https://nim-lang.org/blog.html"), parseUri("/install.html"))
+    assert foo.hostname == "nim-lang.org"
+    assert foo.path == "/install.html"
   result = uris[0]
   for i in 1 ..< uris.len:
     result = combine(result, uris[i])
 
 proc isAbsolute*(uri: Uri): bool =
-  ## returns true if URI is absolute, false otherwise
+  ## Returns true if URI is absolute, false otherwise.
+  runnableExamples:
+    let foo = parseUri("https://nim-lang.org")
+    assert isAbsolute(foo) == true
+    let bar = parseUri("nim-lang")
+    assert isAbsolute(bar) == false
   return uri.scheme != "" and (uri.hostname != "" or uri.path != "")
 
 proc `/`*(x: Uri, path: string): Uri =
-  ## Concatenates the path specified to the specified URI's path.
+  ## Concatenates the path specified to the specified URIs path.
   ##
-  ## Contrary to the ``combine`` procedure you do not have to worry about
-  ## the slashes at the beginning and end of the path and URI's path
+  ## Contrary to the `combine proc <#combine,Uri,Uri>`_ you do not have to worry about
+  ## the slashes at the beginning and end of the path and URIs path
   ## respectively.
   ##
-  ## Examples:
-  ##
-  ## .. code-block::
-  ##   let foo = parseUri("http://example.com/foo/bar") / "/baz"
-  ##   assert foo.path == "/foo/bar/baz"
-  ##
-  ##   let bar = parseUri("http://example.com/foo/bar") / "baz"
-  ##   assert bar.path == "/foo/bar/baz"
-  ##
-  ##   let bar = parseUri("http://example.com/foo/bar/") / "baz"
-  ##   assert bar.path == "/foo/bar/baz"
+  ## **See also:**
+  ## * `combine proc <#combine,Uri,Uri>`_
+  runnableExamples:
+    let foo = parseUri("https://nim-lang.org/foo/bar") / "/baz"
+    assert foo.path == "/foo/bar/baz"
+    let bar = parseUri("https://nim-lang.org/foo/bar") / "baz"
+    assert bar.path == "/foo/bar/baz"
+    let qux = parseUri("https://nim-lang.org/foo/bar/") / "baz"
+    assert qux.path == "/foo/bar/baz"
   result = x
 
   if result.path.len == 0:
@@ -348,6 +395,9 @@ proc `/`*(x: Uri, path: string): Uri =
 
 proc `$`*(u: Uri): string =
   ## Returns the string representation of the specified URI object.
+  runnableExamples:
+    let foo = parseUri("https://nim-lang.org")
+    assert $foo == "https://nim-lang.org"
   result = ""
   if u.scheme.len > 0:
     result.add(u.scheme)