# gizlang:url

the URL Standard (url.spec.whatwg.org) over UTF-8 bytes: the basic URL parser with its state overrides (the API's setters), the host parser (IPv4, IPv6, opaque hosts, and domain to ASCII), and the serializer with the offsets of each part, as ada's url_aggregator keeps them. Node's URL is a thin adapter onto this; gizlang:http's `url` stays the client's narrow view of http URLs.

```gizlang
import * as Url from "gizlang:url";
```

## Types

### `WebUrl`

```gizlang
type WebUrl = { scheme: string; username: string; password: string; hasHost: bool; host: string; port: i64; path: Vec<string>; opaque: bool; hasQuery: bool; query: string; hasFragment: bool; fragment: string; }
```

A URL record: the scheme in lower case; the user name and password percent-encoded; the host serialized when
`hasHost` (a domain in ASCII, a bracketed IPv6 address, a dotted IPv4 address, an opaque host, or "" for an empty host); the port, or
-1; the path segments, or the one opaque path when `opaque`; the query and fragment when present, percent-encoded.

- `scheme`: `string`
- `username`: `string`
- `password`: `string`
- `hasHost`: `bool`
- `host`: `string`
- `port`: `i64`
- `path`: `Vec<string>`
- `opaque`: `bool`
- `hasQuery`: `bool`
- `query`: `string`
- `hasFragment`: `bool`
- `fragment`: `string`

### `WebUrlText`

```gizlang
type WebUrlText = { href: string; protocolEnd: i64; usernameEnd: i64; hostStart: i64; hostEnd: i64; port: i64; pathStart: i64; searchStart: i64; hashStart: i64; kind: i64; }
```

A serialized URL with the offsets of its parts, as Node's urlComponents holds them: the end of "scheme:", the end of
the user name, the start and end of the host, the port (-1 none), the start of the path, of the query's "?" and of
the fragment's "#" (-1 none), and the scheme's kind (0 http, 1 not special, 2 https, 3 ws, 4 ftp, 5 wss, 6 file).

- `href`: `string`
- `protocolEnd`: `i64`
- `usernameEnd`: `i64`
- `hostStart`: `i64`
- `hostEnd`: `i64`
- `port`: `i64`
- `pathStart`: `i64`
- `searchStart`: `i64`
- `hashStart`: `i64`
- `kind`: `i64`

## Functions

### `emptyWebUrl`

```gizlang
function emptyWebUrl(): WebUrl
```

An empty URL record, which the parser fills.

Effects: fail.

### `webUrl`

```gizlang
function webUrl(input: string, base: Option<WebUrl>): Option<WebUrl>
```

INPUT parsed as a URL against BASE when there is one; none is failure.

Effects: fail.

### `specialScheme`

```gizlang
function specialScheme(scheme: string): bool
```

Whether SCHEME is one of the special schemes (ftp, file, http, https, ws, wss).

### `punycodeEncode`

```gizlang
function punycodeEncode(cps: Vec<i64>): Option<bytes>
```

The code points CPS as punycode, or none on overflow.

Effects: fail.

### `punycodeDecode`

```gizlang
function punycodeDecode(input: bytes): Option<Vec<i64>>
```

The punycode INPUT as code points, or none when it is not valid.

Effects: fail.

### `domainToUnicode`

```gizlang
function domainToUnicode(domain: string): string
```

DOMAIN (ASCII, as the host parser gives it) with each punycode label decoded (UTS 46 ToUnicode).

Effects: fail.

### `fileUrl`

```gizlang
function fileUrl(path: string, windows: bool): Option<WebUrl>
```

The file URL of the absolute PATH (Node's pathToFileURL): every byte the parser would read as syntax, trim or leave
as it is percent-encoded first; "\" is a separator when WINDOWS.

Effects: fail.

## Methods

### `WebUrl.serialized`

```gizlang
function WebUrl.serialized(self: WebUrl, excludeFragment: bool): WebUrlText
```

The URL serialized, without its fragment when EXCLUDE_FRAGMENT, with the offsets of its parts.

Effects: fail.

### `WebUrl.href`

```gizlang
function WebUrl.href(self: WebUrl): string
```

The URL serialized.

Effects: fail.

### `WebUrl.setPart`

```gizlang
function WebUrl.setPart(self: mut WebUrl, part: i64, value: string): bool
```

The URL API's setter PART (URL_PROTOCOL...) with VALUE. False when VALUE does not apply: an href that does not
parse, a part this URL cannot have, or a value the setter's parser rejects (which may still have set a part before
it, as the standard's setters do).

Effects: fail.

### `WebUrl.origin`

```gizlang
function WebUrl.origin(self: WebUrl): string
```

The URL's origin serialized: "scheme://host[:port]" for http, https, ws, wss and ftp; a blob: URL's inner http(s)
URL's; else "null".

Effects: fail.

## Constants

### `URL_PROTOCOL`

```gizlang
const URL_PROTOCOL = 0
```

The parts the URL API sets (WebUrl.setPart), numbered as Node's url binding numbers them.

### `URL_HOST`

```gizlang
const URL_HOST = 1
```

The index of the host part in the array that a URL parse gives.

### `URL_HOSTNAME`

```gizlang
const URL_HOSTNAME = 2
```

The index of the hostname part in the array that a URL parse gives.

### `URL_PORT`

```gizlang
const URL_PORT = 3
```

The index of the port part in the array that a URL parse gives.

### `URL_USERNAME`

```gizlang
const URL_USERNAME = 4
```

The index of the username part in the array that a URL parse gives.

### `URL_PASSWORD`

```gizlang
const URL_PASSWORD = 5
```

The index of the password part in the array that a URL parse gives.

### `URL_PATHNAME`

```gizlang
const URL_PATHNAME = 6
```

The index of the pathname part in the array that a URL parse gives.

### `URL_SEARCH`

```gizlang
const URL_SEARCH = 7
```

The index of the search part in the array that a URL parse gives.

### `URL_HASH`

```gizlang
const URL_HASH = 8
```

The index of the hash part in the array that a URL parse gives.

### `URL_HREF`

```gizlang
const URL_HREF = 9
```

The index of the href part in the array that a URL parse gives.

