March Docs

URI

URI module: URL/URI parsing, encoding, and query-string manipulation.

Types: URI(scheme, host, port, path, query, fragment) scheme -- e.g. "https", "http", "" if absent host -- e.g. "example.com" port -- Some(443) or None path -- e.g. "/api/users" (includes leading /) query -- raw query string e.g. "q=hello&page=2" fragment -- fragment identifier e.g. "section-1"

Percent-encoding follows RFC 3986: unreserved chars (A-Z a-z 0-9 - _ . ~) are left as-is; all other bytes are encoded as %XX (uppercase hex).

encode_query / decode_query work with List((String, String)) association lists (not Map) so this module has no stdlib dependencies.

Types

typeURIURI = URI(String, String, Option(Int), String, String, String)#

Functions

fnparseparse(s)#

Parse a URI string into its components.

URI.parse("https://example.com:8080/api/users?q=hello#top") -- URI("https", "example.com", Some(8080), "/api/users", "q=hello", "top")

URI.parse("http://localhost/path") -- URI("http", "localhost", None, "/path", "", "")

URI.parse("/relative/path?foo=bar") -- URI("", "", None, "/relative/path", "foo=bar", "")

Relative URIs (no scheme) are supported; host and port will be empty/None.

fnto_stringto_string(uri)#

Convert a URI back to its string representation.

URI.to_string(URI("https", "example.com", None, "/path", "q=1", "top")) -- "https://example.com/path?q=1#top"

URI.to_string(URI("http", "localhost", Some(4000), "/", "", "")) -- "http://localhost:4000/"

fnencodeencode(s)#

Percent-encode a string for safe use in a URI component.

Unreserved characters (A–Z, a–z, 0–9, -, _, ., ~) are left unchanged; all other bytes are encoded as %XX (uppercase hex).

URI.encode("hello world") -- "hello%20world" URI.encode("foo=bar&baz") -- "foo%3Dbar%26baz" URI.encode("café") -- "caf%C3%A9"

fndecodedecode(s)#

Decode a percent-encoded URI component.

%XX sequences are decoded to their byte values; + is left unchanged (use decode_query for form-encoded values where + means space).

URI.decode("hello%20world") -- "hello world" URI.decode("caf%C3%A9") -- "café" URI.decode("no-encoding") -- "no-encoding"

fnencode_queryencode_query(pairs)#

Encode a list of key-value pairs as a URL query string.

Keys and values are percent-encoded; pairs are joined with "&".

URI.encode_query([("q", "hello world"), ("page", "2")]) -- "q=hello%20world&page=2"

URI.encode_query([]) -- ""

fndecode_querydecode_query(s)#

Decode a URL query string into a list of key-value pairs.

Percent-encoded sequences are decoded; "+" is treated as a space (application/x-www-form-urlencoded convention).

URI.decode_query("q=hello+world&page=2") -- [("q", "hello world"), ("page", "2")]

URI.decode_query("") -- []

fnmergemerge(base, relative)#

Merge a relative URI reference onto a base URI (RFC 3986 §5.2, simplified).

If the relative URI has a scheme, it is used as-is. If it has an authority (host), the base scheme is kept. Otherwise the base scheme and host are preserved, and the path is resolved.

let base = URI.parse("https://example.com/a/b/c") URI.to_string(URI.merge(base, URI.parse("../d"))) -- "https://example.com/a/d"

URI.to_string(URI.merge(base, URI.parse("//other.com/x"))) -- "https://other.com/x"

fnschemescheme(uri)#

Extract the scheme component (e.g. \

fnhosthost(uri)#

Extract the host component (e.g. \

fnportport(uri)#

Extract the port as Some(n) or None.

fnpathpath(uri)#

Extract the path component (e.g. \

fnqueryquery(uri)#

Extract the raw query string (e.g. \

fnfragmentfragment(uri)#

Extract the fragment identifier (e.g. \