is a URI datatype and parser for Carp.
(load "git@github.com:carpentry-org/uri@0.5.1")To get started, you’ll most probably want to parse a URI from a string. To do
so, you use URI.parse. This function will return a URI datatype for you to
work with, or an error type if the URI string was invalid.
If you have a a URI value the simplest operation is probably converting the URI
back to a string using the str interface, which should be idempotent—i.e.
you’ll get the original URI back.
You can also ask the URI for its properties, like the scheme, the port, or the
URI parameters.
URI.query-map parses the query component into a Map String String. Since a
map holds one value per key, repeated keys such as ?tag=a&tag=b keep only the
last value. When repeated keys matter—checkbox lists, multi-select forms,
?id=1&id=2—use URI.query-multimap, which collects every value for a key into
an Array, in the order it appeared:
(def u (Result.unsafe-from-success (URI.parse "http://x/?tag=a&tag=b&sort=asc")))
(URI.query-multimap &u) ; => Success {"tag" ["a" "b"] "sort" ["asc"]}
(URI.query-values &u "tag") ; => ["a" "b"]URI.query-values returns just the values for one key (empty when it is absent),
and URI.query-multimap-from-str does the same as query-multimap for a bare
querystring.
URI.resolve resolves a relative URI reference against a base URI, following
RFC 3986 section 5:
(def base (Result.unsafe-from-success (URI.parse "http://a/b/c/d;p?q")))
(URI.resolve &base "../g") ; => Success http://a/b/g
(URI.resolve &base "/g") ; => Success http://a/g
(URI.resolve &base "?y") ; => Success http://a/b/c/d;p?y
(URI.resolve &base "//h/p") ; => Success http://h/pURI.remove-dot-segments is the underlying path normalizer (RFC 3986 section
5.2.4). It resolves . and .. segments in a path string:
(URI.remove-dot-segments "/a/b/c/./../../g") ; => "/a/g"URI.normalize brings a URI into the canonical form described by RFC 3986
section 6.2, so that two
URIs denoting the same resource compare equal under URI.=:
(def u (Result.unsafe-from-success
(URI.parse "HTTP://User@Example.COM:80/%7Ejoe/./index.html")))
(URI.str &(URI.normalize &u)) ; => "http://User@example.com/~joe/index.html"It lower-cases the scheme and host, upper-cases the hex digits of retained
percent-escapes, decodes percent-escaped unreserved characters, removes ./..
segments from the path, and drops a port that equals the scheme's default. The
case of the userinfo, path, query, and fragment is preserved.
A more complete documentation can be found under https://veitheller.de/uri/!
This datatype and parser was heavily inspired by the one in the Crystal standard library. I cannot thank the people who worked on it enough; they saved me from going through a lot of pain and suffering!
Have fun!