silk.net.address.
IP addresses, ports, endpoints, and the host of a URI, as checked values that do not allocate.
When to use#
Use Host.parse on the host of a URI. It returns a domain name, an IPv4 address, or an IPv6
address. Give the result to silk.net.resolver to get endpoints, and keep it to check the identity
of an HTTPS server. Use Ipv4Address, Ipv6Address, Port, and Endpoint when you
already have a numeric address.
Details#
Addresses store their bytes in network order. A DomainHost keeps the spelling of its input
in a fixed buffer of 253 bytes, and compares without case. The formatInto functions write the
canonical text into a buffer that you give. IPv6 text uses the short lowercase form of RFC 5952,
for example 2001:db8::1.
Errors#
AddressErrortells which rule failed, and the byte offset where it failed.
Gotchas#
Only plain ASCII domains are accepted. Convert an internationalized name to its xn-- form
first. These forms fail: a trailing dot, percent escapes, an IPv6 zone such as %eth0,
IPvFuture, user information, a port, and old IPv4 forms such as 127.1 or 0x7f.0.0.1.
Examples#
Parse hosts and format an address#
import silk.net.address { AddressError, Host, Ipv6Address, Port }
import silk.core.result { Result }
pub fn main() -> i32 {
let host = match Host.parse("[2001:DB8:0:0::1]") {
Result<Host, AddressError>.Success { value } => value
Result<Host, AddressError>.Failure { error: _ } => {
return 1
}
}
let address = match host {
Host.Ipv6 { value } => value
_ => {
return 1
}
}
let mut text: [u8; 64] = [0; 64]
let length = match Ipv6Address.formatInto(&address, &mut text) {
Result<usize, AddressError>.Success { value } => value
Result<usize, AddressError>.Failure { error: _ } => {
return 1
}
}
// The canonical form is "2001:db8::1".
if length != 11 || text[0] != 50 || text[9] != 58 || text[10] != 49 {
return 1
}
let failed = match Port.make(70000) {
Result<Port, AddressError>.Success { value: _ } => false
Result<Port, AddressError>.Failure { error: AddressError.InvalidPort { value } } => value
== 70000
Result<Port, AddressError>.Failure { error: _ } => false
}
if !failed {
return 1
}
return 0
}Import as NetworkAddress with import silk.net.address { NetworkAddress }.
Public declarations: 12.
AddressReason#
pub enum AddressReasonThe rule that rejected an IP address. AddressError.InvalidAddress carries it, with the byte
offset where the check failed.
Empty#
EmptyThe numeric address input is empty.
InvalidCharacter#
InvalidCharacterAn input byte is not admitted in this position.
InvalidComponent#
InvalidComponentAn address component has invalid syntax.
LeadingZero#
LeadingZeroAn IPv4 part has a leading zero, as in 010. The old octal form is not accepted.
ComponentOverflow#
ComponentOverflowAn address component exceeds its numeric range.
WrongComponentCount#
WrongComponentCountThe address has the wrong number of parts: IPv4 needs 4, and IPv6 needs 8 or ::.
MultipleCompression#
MultipleCompressionThe IPv6 text has :: more than one time.
CompressionWithoutOmission#
CompressionWithoutOmissionThe IPv6 text has :: together with all 8 parts, so :: replaces nothing.
Implementation Debug for AddressReason#
impl Debug for AddressReasonOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as Empty.
HostReason#
pub enum HostReasonThe rule that rejected a domain name. AddressError.InvalidHost carries it, with the byte
offset where the check failed.
EmptyName#
EmptyNameThe domain name is empty.
NameTooLong#
NameTooLongThe name is longer than 253 bytes.
EmptyLabel#
EmptyLabelA domain label is empty.
LabelTooLong#
LabelTooLongA label, the part between two dots, is longer than 63 bytes.
Nul#
NulThe domain contains a NUL byte.
NonAscii#
NonAsciiThe domain contains a non-ASCII byte.
InvalidCharacter#
InvalidCharacterAn input byte is not admitted in this position.
EdgeHyphen#
EdgeHyphenA domain label begins or ends with a hyphen.
InvalidALabel#
InvalidALabelA label that starts with xn-- is not a valid Punycode label.
TrailingDot#
TrailingDotThe name ends with a dot, as in example.com..
NumericFinalLabel#
NumericFinalLabelThe last label has only digits, so the name looks like an IPv4 address.
Implementation Debug for HostReason#
impl Debug for HostReasonOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as EmptyName.
UnsupportedHostForm#
pub enum UnsupportedHostFormA host form that is valid in a URI, but that this module does not accept.
IpvFuture#
IpvFutureThe host uses unsupported IPvFuture syntax.
ZoneIdentifier#
ZoneIdentifierThe IPv6 host has a zone, as in [fe80::1%25eth0].
EscapedHost#
EscapedHostThe host contains unsupported percent escapes.
UserInfo#
UserInfoThe input has user information, as in user@host. Give only the host.
PortDelimiter#
PortDelimiterThe input has a port, as in host:80. Give only the host.
UriDelimiter#
UriDelimiterThe input has /, ?, or #. Give only the host.
Implementation Debug for UnsupportedHostForm#
impl Debug for UnsupportedHostFormOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as IpvFuture.
AddressError#
pub union AddressErrorThe error from parsing, checking, or formatting a value in this module.
InvalidAddress#
InvalidAddressThe IP address text is not valid.
Field reason#
pub reason: AddressReasonThe rule that failed.
Field offset#
pub offset: usizeThe zero-based byte offset of the rejected input.
InvalidHost#
InvalidHostThe domain name is not valid.
Field reason#
pub reason: HostReasonThe rule that failed.
Field offset#
pub offset: usizeThe zero-based byte offset of the rejected input.
InvalidPort#
InvalidPortThe port number is more than 65535.
Field value#
pub value: usizeThe number that you gave.
UnsupportedForm#
UnsupportedFormThe host uses a form that this module does not accept.
Field form#
pub form: UnsupportedHostFormThe form that was found.
Field offset#
pub offset: usizeThe zero-based byte offset of the rejected input.
OutputTooSmall#
OutputTooSmallThe output buffer is too small. Nothing was written.
Field required#
pub required: usizeThe number of bytes that the text needs.
Field available#
pub available: usizeThe length of the buffer that you gave.
Implementation Debug for AddressError#
impl Debug for AddressErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant and its fields, such as InvalidAddress { ... }.
Ipv4Address#
pub struct Ipv4AddressAn IPv4 address, as 4 bytes in network order.
Ipv6Address#
pub struct Ipv6AddressAn IPv6 address, as 16 bytes in network order.
IpAddress#
pub union IpAddressAn IPv4 or an IPv6 address.
V4#
V4An IPv4 address.
Field value#
pub value: Ipv4AddressThe four network-order IPv4 octets.
V6#
V6An IPv6 address.
Field value#
pub value: Ipv6AddressThe sixteen network-order IPv6 octets.
Port#
pub struct PortA TCP or UDP port, from 0 to 65535. Port 0 is accepted, for example to let the system choose the port of a listener.
Endpoint#
pub struct EndpointAn IP address and a port that you can connect to.
DomainHost#
pub struct DomainHostA checked ASCII domain name, such as example.com. It keeps the spelling of its input, and
compares without case.
It stores the name in a fixed buffer of 253 bytes and does not allocate. Only plain ASCII names
are accepted. Convert an internationalized name to its xn-- form first.
Host#
pub union HostThe host of a URI: a domain name, an IPv4 address, or an IPv6 address. Make it with
Host.parse.
Domain#
DomainA validated ASCII domain host.
Field value#
pub value: DomainHostThe domain name, spelled as in the input.
Ipv4#
Ipv4An owned IPv4 origin host.
Field value#
pub value: Ipv4AddressThe four network-order IPv4 octets.
Ipv6#
Ipv6An owned IPv6 origin host.
Field value#
pub value: Ipv6AddressThe sixteen network-order IPv6 octets.
NetworkAddress#
pub struct NetworkAddressThe namespace of this module. The functions are on the value types.
Implementation Copy for AddressError#
impl Copy for AddressErrorImplementation Copy for Ipv4Address#
impl Copy for Ipv4AddressImplementation Copy for Ipv6Address#
impl Copy for Ipv6AddressImplementation Copy for IpAddress#
impl Copy for IpAddressImplementation Copy for Port#
impl Copy for PortImplementation Copy for Endpoint#
impl Copy for EndpointImplementation Copy for DomainHost#
impl Copy for DomainHostImplementation Copy for Host#
impl Copy for HostImplementation Ipv4Address#
impl Ipv4AddressAssociated function fromOctets#
pub fn fromOctets(octets: [u8; 4]) -> Ipv4AddressReturns the IPv4 address with these 4 bytes, in network order.
Associated function parse#
pub fn parse(text: string) -> Result<Ipv4Address, AddressError>Parses decimal dotted text, such as 192.0.2.1. Each part is 0 to 255 without leading zeros.
Associated function parseBytes#
pub fn parseBytes(bytes: &[u8]) -> Result<Ipv4Address, AddressError>Parses decimal dotted text, such as 192.0.2.1. Each part is 0 to 255 without leading zeros.
When to use#
Use it for text that you have as bytes, such as part of a request you read. For a string,
use Ipv4Address.parse.
Method octets#
pub fn octets(self: &Self) -> [u8; 4]Returns the owned network-order octets by value.
Method equals#
pub fn equals(self: &Self, other: &Self) -> boolReports exact binary equality.
Method formatInto#
pub fn formatInto(self: &Self, output: &mut [u8]) -> Result<usize, AddressError>Writes the canonical text to the start of output, and returns its length. If output is too
small, it writes nothing and returns OutputTooSmall.
Implementation Ipv6Address#
impl Ipv6AddressAssociated function fromOctets#
pub fn fromOctets(octets: [u8; 16]) -> Ipv6AddressReturns the IPv6 address with these 16 bytes, in network order.
Associated function parse#
pub fn parse(text: string) -> Result<Ipv6Address, AddressError>Parses hexadecimal IPv6 text, such as 2001:db8::1, without brackets or a zone. A dotted IPv4
end, as in ::ffff:192.0.2.1, is not accepted.
Associated function parseBytes#
pub fn parseBytes(bytes: &[u8]) -> Result<Ipv6Address, AddressError>Parses hexadecimal IPv6 text, such as 2001:db8::1, without brackets or a zone. A dotted IPv4
end, as in ::ffff:192.0.2.1, is not accepted.
When to use#
Use it for text that you have as bytes, such as part of a request you read. For a string,
use Ipv6Address.parse.
Method octets#
pub fn octets(self: &Self) -> [u8; 16]Returns the owned network-order octets by value.
Method equals#
pub fn equals(self: &Self, other: &Self) -> boolReports exact binary equality.
Method formatInto#
pub fn formatInto(self: &Self, output: &mut [u8]) -> Result<usize, AddressError>Writes the canonical lowercase text, such as 2001:db8::1, to the start of output, and
returns its length. If output is too small, it writes nothing and returns OutputTooSmall.
Implementation IpAddress#
impl IpAddressMethod isV4#
pub fn isV4(self: &Self) -> boolReturns true for an IPv4 address.
Method equals#
pub fn equals(self: &Self, other: &Self) -> boolReturns true if the two addresses are of the same family and have the same bytes. An IPv4
address never equals an IPv6 address, also not an IPv4-mapped one.
Method formatInto#
pub fn formatInto(self: &Self, output: &mut [u8]) -> Result<usize, AddressError>Writes the canonical text of the IPv4 or IPv6 address to the start of output, and returns
its length. IPv6 has no brackets.
Implementation Port#
impl PortAssociated function make#
pub fn make(value: usize) -> Result<Port, AddressError>Returns the port, or InvalidPort if value is more than 65535.
Associated function fromU16#
pub fn fromU16(value: u16) -> PortReturns the port with this number. Every u16 is a valid port.
Method value#
pub fn value(self: &Self) -> u16Returns the port number.
Implementation Endpoint#
impl EndpointAssociated function make#
pub fn make(address: IpAddress, port: Port) -> EndpointReturns the endpoint for address and port.
Method address#
pub fn address(self: &Self) -> IpAddressReturns the owned address by value.
Method port#
pub fn port(self: &Self) -> PortReturns the checked port by value.
Method equals#
pub fn equals(self: &Self, other: &Self) -> boolReports exact address-and-port equality.
Implementation DomainHost#
impl DomainHostAssociated function make#
pub fn make(text: string) -> Result<DomainHost, AddressError>Checks the text text as a domain name and copies it.
Details#
The name must be plain ASCII, 1 to 253 bytes, with labels of 1 to 63 bytes that do not begin
or end with a hyphen. A label that starts with xn-- must be valid Punycode. The last label
must not be only digits.
Errors#
AddressError.InvalidHostwith aHostReasonand the byte offset if a rule fails. A trailing dot, as inexample.com., fails withTrailingDot.
Gotchas#
Convert an internationalized name to its xn-- form first.
Associated function makeBytes#
pub fn makeBytes(bytes: &[u8]) -> Result<DomainHost, AddressError>Checks bytes as a domain name and copies it.
When to use#
Use it for a name that you have as bytes, such as part of a request you read. For a string,
use DomainHost.make.
Details#
The name must be plain ASCII, 1 to 253 bytes, with labels of 1 to 63 bytes that do not begin
or end with a hyphen. A label that starts with xn-- must be valid Punycode. The last label
must not be only digits.
Errors#
AddressError.InvalidHostwith aHostReasonand the byte offset if a rule fails. A trailing dot, as inexample.com., fails withTrailingDot.
Gotchas#
Convert an internationalized name to its xn-- form first.
Method bytes#
pub fn bytes<'a>(self: &'a Self) -> &'a [u8]Returns the name, spelled as in the input.
Method length#
pub fn length(self: &Self) -> usizeReturns the stored byte length.
Method equals#
pub fn equals(self: &Self, other: &Self) -> boolReturns true if the names are equal without case, so Example.COM equals example.com.
Implementation Host#
impl HostAssociated function parse#
pub fn parse(text: string) -> Result<Host, AddressError>Parses the host part of a URI.
Details#
[...] is parsed as IPv6, decimal dotted text is parsed as IPv4, and all other text as a
domain name. Give only the host, without user information or a port. The result does not
allocate. Give it to silk.net.resolver to get endpoints, and keep it to check the identity of
an HTTPS server.
Errors#
AddressErrorwith the rule that failed and the byte offset where it failed.
Gotchas#
These forms fail: a trailing dot, percent escapes, an IPv6 zone such as %eth0, IPvFuture,
user information, a port, non-ASCII names, and old IPv4 forms such as 127.1 or
0x7f.0.0.1.
Associated function parseBytes#
pub fn parseBytes(bytes: &[u8]) -> Result<Host, AddressError>Parses the host part of a URI.
When to use#
Use it for a host that you have as bytes, such as the host of a URI you parsed. For a
string, use Host.parse.
Details#
[...] is parsed as IPv6, decimal dotted text is parsed as IPv4, and all other text as a
domain name. Give only the host, without user information or a port. The result does not
allocate. Give it to silk.net.resolver to get endpoints, and keep it to check the identity of
an HTTPS server.
Errors#
AddressErrorwith the rule that failed and the byte offset where it failed.
Gotchas#
These forms fail: a trailing dot, percent escapes, an IPv6 zone such as %eth0, IPvFuture,
user information, a port, non-ASCII names, and old IPv4 forms such as 127.1 or
0x7f.0.0.1.
Method numeric#
pub fn numeric(self: &Self) -> IpAddress | ()Returns the IP address of a numeric host, or () for a domain name.
Implementation Display for Ipv4Address#
impl Display for Ipv4AddressOperation display#
effect fn display(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterImplementation Display for Ipv6Address#
impl Display for Ipv6AddressOperation display#
effect fn display(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterImplementation Display for IpAddress#
impl Display for IpAddressOperation display#
effect fn display(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterImplementation Display for DomainHost#
impl Display for DomainHostOperation display#
effect fn display(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterCategory: Networking.
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.