URL structure
Copyright (C) 2025-2026 Trayambak Rai (xtrayambak@disroot.org)
Types
Input = string | seq[char]
Output = object url*: Option[URL] violations*: seq[SyntaxViolation]
ParseError {.pure, size: 1.} = enum EmptyUrlBuffer = "empty URL buffer", EmptyHost = "empty host", IdnaError = "invalid international domain name", InvalidPort = "invalid port number", InvalidIpv4Address = "invalid IPv4 address", ForbiddenCodePointInOpaqueHost = "forbidden code point in opaque host", InvalidIpv6Address = "invalid IPv6 address", InvalidDomainCharacter = "invalid domain character", RelativeUrlWithoutBase = "relative URL without a base", InvalidUrlUnit = "found a character which is neither a URL code point, nor % in the fragment", RelativeUrlWithCannotBeBeABaseBase = "relative URL with a cannot-be-a-base base", SetHostOnCannotBeABaseUrl = "a cannot-be-a-base URL doesn\'t have a host to set", TooLarge = "URLs more than 4 GB are not supported", MissingSchemeNonRelativeUrl = "the input is missing a scheme", HostMissing = "the input has a special scheme, but does not contain a host", CannotDecodeHost = "the host cannot be decoded into ASCII"
SchemeType {.pure, size: 1.} = enum Http = 0, NotSpecial = 1, Https = 2, Ws = 3, Ftp = 4, Wss = 5, File = 6
SyntaxViolation {.pure, size: 1.} = enum Backslash = "backslash", C0SpaceIgnored = "leading or trailing control or space character are ignored in URLs", EmbeddedCredentials = "embedding authentication information (username or password) in an URL is not recommended", ExpectedDoubleSlash = "expected //", ExpectedFileDoubleSlash = "expected // after file:", FileWithHostAndWindowsDrive = "file: with host and Windows drive letter", NonUrlCodePoint = "non-URL code point", NullInFragment = "NULL characters are ignored in URL fragment identifiers", PercentDecode = "expected 2 hex digits after %", TabOrNewlineIgnored = "tabs or newlines are ignored in URLs", UnencodedAtSign = "unencoded @ sign in username or password"
URL = object pathname*: string
- This is the core URL structure outputted by this library. See: https://url.spec.whatwg.org/#url-representation
URLFlag {.pure, size: 1.} = enum HasHostname, ## The URL has a valid hostname parameter. HasQuery, ## The URL has a valid query/search parameter. HasFragment, ## The URL has a valid fragment/hash parameter. HasPort, ## The URL has a valid port parameter. HasOpaquePath ## The URL has an opaque path parameter.
Procs
func clearPathname(url: var URL) {.inline, ...raises: [], tags: [], forbids: [].}
func clearQuery(url: var URL) {.inline, ...raises: [], tags: [], forbids: [].}
func copyScheme(dest: var URL; source: URL) {.inline, ...raises: [], tags: [], forbids: [].}
func defaultPort(scheme: string): Option[uint16] {.inline, ...raises: [], tags: [], forbids: [].}
func flags(url: URL): set[URLFlag] {.inline, ...raises: [], tags: [], forbids: [].}
-
The URL struct uses URLFlag(s) internally to keep the data in a desirable layout. This getters lets you read these flags for your own logic.
Note: These flags are only mutable via the setters provided, and cannot be manually mutated, just to ensure coherency and prevent bugs.
func getSchemeType(url: URL): SchemeType {.inline, ...raises: [], tags: [], forbids: [].}
func hasOpaquePath(url: URL): bool {.inline, ...raises: [], tags: [], forbids: [].}
func hasOpaquePath=(url: var URL; flag: bool) {.inline, ...raises: [], tags: [], forbids: [].}
func isFile(typ: SchemeType): bool {.inline, ...raises: [], tags: [], forbids: [].}
func isSpecial(typ: SchemeType): bool {.inline, ...raises: [], tags: [], forbids: [].}
func nonSpecialScheme=(url: var URL; input: string) {.inline, ...raises: [], tags: [], forbids: [].}
func schemeType=(url: var URL; input: SchemeType) {.inline, ...raises: [], tags: [], forbids: [].}
func toSchemeType(value: string): SchemeType {.inline, ...raises: [], tags: [], forbids: [].}
func updateBaseQuery(url: var URL; input: Option[string]) {.inline, ...raises: [], tags: [], forbids: [].}
func updateBaseQuery(url: var URL; input: Option[string]; queryPercentEncodeSet: openArray[uint8]) {.inline, ...raises: [], tags: [], forbids: [].}
func updateEncodedFragment(url: var URL; input: Option[string]) {.inline, ...raises: [], tags: [], forbids: [].}