## When To Use std.url In Zerolang, use `std.url` for lexical URL splitting, percent encoding, decoded query lookup, form-urlencoded bodies, and query appending. Runnable today: | API | Return | Notes | | --- | --- | --- | | `std.url.percentEncode(buffer, bytes)` | `Maybe>` | Percent-encodes bytes into caller storage. | | `std.url.percentDecode(buffer, bytes)` | `Maybe>` | Percent-decodes bytes into caller storage. | | `std.url.queryEscape(buffer, bytes)` | `Maybe>` | Query-escapes bytes, using `+` for spaces. | | `std.url.queryUnescape(buffer, bytes)` | `Maybe>` | Query-unescapes bytes, converting `+` back to space. | | `std.url.scheme(url)` | `Maybe>` | Borrows the URL scheme if present. | | `std.url.authority(url)` | `Maybe>` | Borrows the URL authority if present. | | `std.url.host(url)` | `Maybe>` | Borrows the host from the URL authority. | | `std.url.path(url)` | `Span` | Borrows the path or an empty suffix. | | `std.url.query(url)` | `Maybe>` | Borrows the raw query string if present. | | `std.url.fragment(url)` | `Maybe>` | Borrows the raw fragment if present. | | `std.url.queryValue(query, key)` | `Maybe>` | Borrows a raw query parameter value by key. | | `std.url.queryValueDecoded(buffer, query, key)` | `Maybe>` | Looks up a raw or escaped query key and writes the decoded value. | | `std.url.writeQueryParam(buffer, key, value)` | `Maybe>` | Writes an escaped `key=value` query parameter. | | `std.url.writeFormField(buffer, key, value)` | `Maybe>` | Writes one application/x-www-form-urlencoded field. | | `std.url.appendFormField(buffer, form, field)` | `Maybe>` | Appends one encoded field to an existing form body. | | `std.url.formValue(buffer, form, key)` | `Maybe>` | Looks up a form field by raw or escaped key and writes the decoded value. | | `std.url.appendQuery(buffer, base, query)` | `Maybe>` | Writes a URL with an appended raw query segment. | | `std.url.writeUrl(buffer, scheme, host, path)` | `Maybe>` | Writes a `scheme://host/path` URL. | | `std.url.appendFragment(buffer, base, fragment)` | `Maybe>` | Writes a URL with an appended raw fragment. | Metadata labels: - effects: parse - allocation behavior: no allocation; writers use caller storage - target support: target-neutral - error behavior: `Maybe` helpers return null on malformed input or insufficient storage - ownership notes: borrowed slices point into the input; encoded output points into caller storage - examples: `conformance/native/pass/std-codec-json-url.graph` ## Example ```zero pub fn main(world: World) -> Void raises { let url: Span = "https://example.com/path?q=zero%20lang#part" let host: Maybe> = std.url.host(url) let query: Maybe> = std.url.query(url) let fragment: Maybe> = std.url.fragment(url) var out: [48]u8 = [0_u8; 48] var param_buf: [16]u8 = [0_u8; 16] let param: Maybe> = std.url.writeQueryParam(param_buf, "q", "zero lang") var decoded_buf: [16]u8 = [0_u8; 16] var decoded: Maybe> = null var next: Maybe> = null if param.has { next = std.url.appendQuery(out, "https://example.com/path", param.value) } if query.has { decoded = std.url.queryValueDecoded(decoded_buf, query.value, "q") } if host.has && query.has && fragment.has && decoded.has && next.has && std.mem.eql(host.value, "example.com") && std.mem.eql(decoded.value, "zero lang") { check world.out.write("url ok\n") } } ``` ## Design Notes URL helpers are lexical and byte-oriented. They do not resolve DNS, normalize paths, or allocate. Decoding rejects malformed percent escapes. Form helpers use the same encoding as query strings: spaces become `+`, and other non-unreserved bytes are percent-escaped. URL builders expect path, query, and fragment bytes that are already escaped for their position.