std/uri
Strict ASCII RFC 3986 references, stored with their original encoded spelling. Syntax validation does not impose DNS, scheme or port-range policy. Generic percent decoding and query forms are separate operations. All public failures are Result values. Parse offsets name bytes of the whole input; build and resolve offsets name bytes of the rejected field. Codec offsets name input bytes, including the whole query for forms. Scans and assembly are linear.
Uri
Uri = (Parts) Parts
Parts = ( Authority
Authority = (userinfo = Option(String), host = Host, port = Option(String)) Host
Host = RegName | IpLiteral UriPart
UriPart = WholePart UriProblem
UriProblem = BadCharacter UriError
UriError = (part = UriPart, offset = Int, problem = UriProblem) CodecError
CodecError = BadEscape | NonAscii | InvalidUtf8 | UnalignedBits parse
Parses without repairing, decoding or normalizing any component.
parse = (text : String) -> Result(Uri, UriError) { build
Validates raw candidate fields and their cross-field grammar constraints.
build = (parts : Parts) -> Result(Uri, UriError) { validated(parts, False) } parts
Projects the original raw fields in constant field work.
parts = (uri : Uri) -> Parts { to_string
Reassembles raw spelling, preserving missing versus empty delimiters.
to_string = (uri : Uri) -> String { has_scheme
has_scheme = (uri : Uri) -> Bool { parts(uri).scheme != None } resolve
Strict RFC 5.2 resolution over encoded paths, followed by build validation.
resolve = (base : Uri, reference : Uri) -> Result(Uri, UriError) { encode_component
UTF-8 percent encoding, preserving only the unreserved ASCII alphabet.
encode_component = (text : String) -> String { encode_bytes
encode_bytes = (bytes : BitArray) -> Result(String, CodecError) { decode_component
Decodes once, leaves plus unchanged, then validates UTF-8.
decode_component = (text : String) -> Result(String, CodecError) { decode_bytes
Decodes arbitrary octets; literal ASCII has no component grammar restriction.
decode_bytes = (text : String) -> Result(BitArray, CodecError) { parse_query
Ordered query form pairs. Empty pieces are skipped; semicolons are data.
parse_query = (query : String) -> Result(List((String, String)), CodecError) { build_query
Encodes UTF-8 form pairs without sorting, always including equals signs.
build_query = (pairs : List((String, String))) -> String {