silk.uri.components.
Build a URI reference from its components, or change the components of a parsed one.
When to use#
Use UriComponents to make a URL from parts, such as a host from a configuration file and a
path from user input, or to change one part of a parsed URL. Give each part as raw bytes, which
are encoded for you, or as text that is already encoded. To only read a URL, use
silk.uri.reference.
Details#
UriComponents.make returns an empty relative reference, and UriComponents.fromReference
borrows each part of a parsed reference. Change the public fields, and then call
UriComponents.serializeOwned, UriComponents.serializeInto, or
UriComponents.buildOwned. Raw values are percent-encoded for their component with
silk.uri.percent. Encoded values keep their escape spelling. Each part is checked before
anything is written, and the result is parsed again to make sure that it is a valid reference.
Errors#
ParseErrorif a part is not valid. The offset is a position in that part, or a position in the output if the parts do not make a valid reference together.OutOfMemoryErrorfrom the functions that allocate.
Examples#
Build a URL with encoded parts#
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
import silk.core.option { Option }
import silk.core.result { Result }
import silk.text.string { String }
import silk.uri.components { Authority, ComponentValue, Host, Serialization, UriComponents }
import silk.uri.reference { ParseError }
pub effect fn main() -> i32
! OutOfMemoryError {
let mut allocator = Allocator.systemAllocatorProvider()
let mut parts = UriComponents<'static>.make()
parts.scheme = Option<string<'static>>.some("https")
parts.authority = Option<Authority<'static>>.some(
Authority<'static> {
userinfo: Option<ComponentValue<'static>>.none(),
host: Host<'static>.RegName {
value: ComponentValue<'static>.Encoded { text: "example.com" }
},
port: Option<string<'static>>.none()
}
)
parts.path = ComponentValue<'static>.Raw { bytes: b"/my files" }
parts.query = Option<ComponentValue<'static>>.some(
ComponentValue<'static>.Raw { bytes: b"q=tea time" }
)
let built = run UriComponents.serializeOwned(&parts, Serialization.Full)
|> Effect.provideMut<Allocator>(&mut allocator)
return match move built {
Result<String, ParseError>.Success { value } => {
if String.view(&value) != "https://example.com/my%20files?q=tea%20time" {
return 1
}
return 0
}
Result<String, ParseError>.Failure { error: _ } => 1
}
}Import as UriComponents with import silk.uri.components { UriComponents }.
Public declarations: 5.
ComponentValue#
pub union ComponentValue<'text>The value of a component: raw bytes to encode, or text that is already encoded.
Raw#
RawRaw bytes. Each byte that the component does not allow is percent-encoded.
Field bytes#
pub bytes: &'text [u8]The bytes to encode. A % is data, so it becomes %25.
Encoded#
EncodedText that is already encoded. It is checked, and its escapes are written as they are.
Field text#
pub text: string<'text>The encoded text. It must not contain the delimiters of other components, such as ? in a
path.
Host#
pub union Host<'text>The host of an authority: a name or an IP literal.
RegName#
RegNameA registered name or an IPv4 address. A raw value is encoded with RegName rules.
Field value#
pub value: ComponentValue<'text>The host name. It can be empty.
IpLiteral#
IpLiteralAn IPv6 or IPvFuture literal. It must be valid host syntax.
Field text#
pub text: string<'text>The literal with its brackets, such as [2001:db8::1].
Authority#
pub struct Authority<'text>The authority of a URI: optional user information, a host, and an optional port.
Field userinfo#
pub userinfo: Option<ComponentValue<'text>>The user information, or None. A present empty value writes @ with nothing before it.
Field host#
pub host: Host<'text>The host.
Field port#
pub port: Option<string<'text>>The port as decimal digits, or None. A present empty value writes : with no digits.
Serialization#
pub enum SerializationThe components that a serialization writes.
Full#
FullAll components. Present empty components keep their delimiters.
WithoutAuthentication#
WithoutAuthenticationAll components except the user information and its @. Use it to log or show a URL without
its credentials.
PathAndQuery#
PathAndQueryOnly the path and the query, such as the target of an HTTP request line.
UriComponents#
pub struct UriComponents<'text>The components of a URI reference, as fields that you can change.
The fields borrow their bytes or text. An absent component (None) and a present empty
component are different. The path is always present, but it can be empty.
Field scheme#
pub scheme: Option<string<'text>>The scheme without the :, or None for a relative reference.
Field authority#
pub authority: Option<Authority<'text>>The authority without the //, or None.
Field path#
pub path: ComponentValue<'text>The full path, with its / separators. A raw path keeps / and encodes ? and #.
Field query#
pub query: Option<ComponentValue<'text>>The query without the ?, or None.
Field fragment#
pub fragment: Option<ComponentValue<'text>>The fragment without the #, or None.
Implementation UriComponents<'text>#
impl<'text> UriComponents<'text>Associated function make#
pub fn make() -> UriComponents<'text>Returns an empty relative reference: no scheme, no authority, an empty path, no query, and no fragment.
Associated function fromReference#
pub fn fromReference(reference: &UriReference<'text>) -> UriComponents<'text>Returns the components of reference as encoded values that borrow from it.
If you change nothing, Full serialization gives the original text again.
Associated function serializeInto#
pub effect fn serializeInto(output: &mut Bytes, self: &Self, selection: Serialization) -> Result<
(),
ParseError,
> ! OutOfMemoryError ? &mut AllocatorReplaces the contents of output with the components that selection names.
In a reference without a scheme, a : in the first segment of a raw path is encoded, so the
segment cannot look like a scheme. If output has enough capacity, it does not allocate.
Errors#
Failurewith aParseErrorif a component is not valid. The offset is a position in that component, andoutputdoes not change. The components thatselectionleaves out are also checked.Failurewith aParseErrorif the result is not a valid reference. The offset is a position inoutput, which holds the text that failed.OutOfMemoryErrorif theAllocatorfails or the size does not fit inusize.outputdoes not change.
Gotchas#
PathAndQuery can give text that is not a complete URI reference.
Method serializeOwned#
pub effect fn serializeOwned(self: &Self, selection: Serialization) -> Result<String, ParseError>
! OutOfMemoryError
? &mut AllocatorReturns the components that selection names as a new string.
It allocates exactly the needed size, and nothing for an empty result.
Errors#
Failurewith aParseErrorif a component is not valid, or the result is not a valid reference.OutOfMemoryErrorif theAllocatorfails or the size does not fit inusize.
Method buildOwned#
pub effect fn buildOwned(self: &Self) -> Result<OwnedUriReference, ParseError>
! OutOfMemoryError
? &mut AllocatorReturns all components as a new OwnedUriReference. The text is not copied again.
Errors#
Failurewith aParseErrorif a component is not valid, or the result is not a valid reference.OutOfMemoryErrorif theAllocatorfails.
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.