silk.uri.reference.
Parse a URI or a relative reference (RFC 3986) and read its components without allocation.
When to use#
Use UriReference.parse for text that can be relative, such as an HTML href, a redirect
Location, or a request target like /search?q=silk. Use silk.uri.uri when the text must have a
scheme. To change components or build a reference, use silk.uri.components. To decode the
escapes in a component, use silk.uri.percent.
Details#
UriReference.parse checks the generic syntax of RFC 3986 and returns a view that borrows the
input. The component functions return slices of the input, so nothing is decoded or normalized:
the case of letters and the spelling of %XX escapes do not change. An absent component and an
empty component are different: http://a/ has no query, but http://a/? has an empty query.
OwnedUriReference holds the text and the parsed ranges together, for a value that lives
longer than its input.
Errors#
UriReference.parse returns a ParseError with the cause, the component, and the byte
position.
Gotchas#
The parser checks syntax only. It does not check that a scheme is known, that a host exists, or
that a port is in range. Raw non-ASCII bytes, spaces, and IPv6 zone identifiers are not valid
RFC 3986 syntax. Encode them with silk.uri.percent first.
Examples#
Read the parts of a relative reference#
import silk.core.option { Option }
import silk.core.result { Result }
import silk.uri.reference { ParseError, UriReference }
pub fn main() -> i32 {
let reference = match UriReference.parse("/search?q=silk#results") {
Result<UriReference, ParseError>.Success { value } => value
Result<UriReference, ParseError>.Failure { error: _ } => {
return 1
}
}
let relative = match UriReference.scheme(&reference) {
Option<string>.Some { value: _ } => false
Option<string>.None => true
}
let query = UriReference.query(&reference) |> Option<string>.unwrapOr("")
if !relative || UriReference.path(&reference) != "/search" || query != "q=silk" {
return 1
}
return 0
}Find the position of a syntax error#
import silk.core.result { Result }
import silk.uri.reference { Component, ParseError, ParseReason, UriReference }
pub fn main() -> i32 {
return match UriReference.parse("http://example.com:80a/") {
Result<UriReference, ParseError>.Failure { error } => {
if error.reason != ParseReason.InvalidPort || error.component != Component.Port
|| error.offset != 21 {
return 1
}
return 0
}
Result<UriReference, ParseError>.Success { value: _ } => 1
}
}Import as UriReference with import silk.uri.reference { UriReference }.
Public declarations: 6.
HostKind#
pub enum HostKindThe form of a host, from UriReference.hostKind.
RegName#
RegNameA registered name, such as example.com. An empty host also has this kind.
Ipv4#
Ipv4An IPv4 address in dotted decimal form, such as 192.0.2.1. An octet with more than one digit
must not start with 0.
Ipv6#
Ipv6An IPv6 address in brackets, such as [2001:db8::1]. A zone identifier is not allowed.
IpvFuture#
IpvFutureA future IP literal in brackets, such as [v1.x].
Implementation Debug for HostKind#
impl Debug for HostKindOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as RegName.
Component#
pub enum ComponentA component of a URI reference.
Scheme#
SchemeThe scheme, such as https, without the :.
Authority#
AuthorityThe authority after //: user information, host, and port.
Userinfo#
UserinfoThe user information before @.
Host#
HostThe registered name or IP literal.
Port#
PortThe decimal port after the : of the authority.
Path#
PathThe path, up to ? or #.
Query#
QueryThe query after ?.
Fragment#
FragmentThe fragment after #.
Implementation Debug for Component#
impl Debug for ComponentOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as Scheme.
ParseReason#
pub enum ParseReasonThe cause of a ParseError.
InvalidCharacter#
InvalidCharacterA byte that the component does not allow, such as a space or a non-ASCII byte.
InvalidPercentEscape#
InvalidPercentEscapeA % that is not followed by two hexadecimal digits.
InvalidScheme#
InvalidSchemeA scheme that is empty or does not start with a letter followed by letters, digits, +, -,
or ..
InvalidHost#
InvalidHostAn IP literal or a host that does not follow the host grammar.
InvalidPort#
InvalidPortA port that has a byte that is not a decimal digit.
MissingScheme#
MissingSchemeThe text has no scheme, but a function such as Uri.parse needs one.
Implementation Debug for ParseReason#
impl Debug for ParseReasonOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as InvalidCharacter.
ParseError#
pub struct ParseErrorA URI syntax error: the cause, the component, and the byte position.
Field reason#
pub reason: ParseReasonThe cause of the error.
Field component#
pub component: ComponentThe component that has the error.
Field offset#
pub offset: usizeThe position of the byte that is not valid, from the start of the text. If required syntax is missing, it is the position where it must be.
Implementation Copy for ParseError#
impl Copy for ParseErrorImplementation Debug for ParseError#
impl Debug for ParseErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the fields, as ParseError { reason: ..., component: ..., ... }.
UriReference#
pub struct UriReference<'text>A parsed URI reference that borrows its text.
It is Copy and does not allocate. It cannot live longer than its text. Use
UriReference.copy or UriReference.parseOwned to get an OwnedUriReference.
The component functions return slices of the input, so nothing is decoded or normalized: the
case of letters and the spelling of %XX escapes do not change. An absent component and an
empty component are different: http://a/ has no query, but http://a/? has an empty query.
Gotchas#
The parser checks syntax only. It does not check that a scheme is known, that a host exists, or that a port is in range.
Implementation Copy for UriReference<'text>#
impl<'text> Copy for UriReference<'text>Implementation UriReference<'text>#
impl<'text> UriReference<'text>Associated function parse#
pub fn parse(text: string<'text>) -> Result<UriReference<'text>, ParseError>Parses text as a URI reference: a URI with a scheme, or a relative reference.
It does not allocate, decode, or normalize. If a host is a valid IPv4 address, its kind is
Ipv4, not RegName.
Errors#
ParseErrorfor the first syntax problem, with its component and byte position.
Associated function validateComponent#
pub fn validateComponent(text: string, component: Component) -> Option<ParseError>Checks that text is valid encoded text for one component, and returns the error or None.
The error offset is a position in text. A host can be a registered name or an IP literal
in brackets, but not user information or a port. An empty host or port is valid.
Gotchas#
For a path, it checks only the bytes. Some paths are not valid in every position, for example
a path that starts with // when there is no authority.
Method copy#
pub effect fn copy(self: &Self) -> OwnedUriReference ! OutOfMemoryError ? &mut AllocatorReturns an OwnedUriReference with a copy of the text. It does not parse again.
Errors#
OutOfMemoryErrorif theAllocatorfails.
Associated function parseOwned#
pub effect fn parseOwned(text: string<'text>) -> Result<OwnedUriReference, ParseError>
! OutOfMemoryError
? &mut AllocatorParses text and returns an OwnedUriReference with a copy of it.
Errors#
Failurewith aParseErroriftextis not valid. Nothing is allocated.OutOfMemoryErrorif theAllocatorfails.
Method format#
pub fn format(self: &Self) -> string<'text>Returns the full text of the reference, as it was parsed.
Method scheme#
pub fn scheme(self: &Self) -> Option<string<'text>>Returns the scheme without the :, or None for a relative reference. The case of the
letters does not change.
Method authority#
pub fn authority(self: &Self) -> Option<string<'text>>Returns the authority without the //. Returns None if the component is absent. A component
that is present but empty, such as the query of http://a/?, returns Some("").
Method userinfo#
pub fn userinfo(self: &Self) -> Option<string<'text>>Returns the user information without the @. Returns None if the component is absent. A
component that is present but empty, such as the query of http://a/?, returns Some("").
The text is not split at : into a user name and a password.
Method host#
pub fn host(self: &Self) -> Option<string<'text>>Returns the host, with the brackets of an IP literal. Returns None if there is no authority.
The host of file:///x is present and empty.
Method port#
pub fn port(self: &Self) -> Option<string<'text>>Returns the port digits without the :. Returns None if the component is absent. A
component that is present but empty, such as the query of http://a/?, returns Some("").
It does not convert the port to a number or check its range.
Method path#
pub fn path(self: &Self) -> string<'text>Returns the path. The path is always present, but it can be empty.
Method query#
pub fn query(self: &Self) -> Option<string<'text>>Returns the query without the ?. Returns None if the component is absent. A component that
is present but empty, such as the query of http://a/?, returns Some("").
Method fragment#
pub fn fragment(self: &Self) -> Option<string<'text>>Returns the fragment without the #. Returns None if the component is absent. A component
that is present but empty, such as the query of http://a/?, returns Some("").
Method hostKind#
pub fn hostKind(self: &Self) -> Option<HostKind>Returns the HostKind of the host, or None if there is no authority.
OwnedUriReference#
pub struct OwnedUriReferenceA URI reference that owns its text and its parsed ranges.
Get one from UriReference.copy, UriReference.parseOwned, or
OwnedUriReference.fromString. OwnedUriReference.view returns a UriReference without
parsing again.
Implementation OwnedUriReference#
impl OwnedUriReferenceAssociated function fromString#
pub fn fromString(text: String) -> Result<OwnedUriReference, ParseError>Parses text and keeps it, without a copy or an allocation.
Errors#
Failurewith aParseErroriftextis not valid.
Gotchas#
It consumes text also when it fails.
Method view#
pub fn view(self: &Self) -> UriReferenceReturns a UriReference that borrows this value. It does not parse again or allocate.
Method intoString#
pub fn intoString(self: Self) -> StringReturns the text and consumes the value. It does not copy.
Category: Data formats.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.