Die Standardbibliothek

Jedes Modul der Standardbibliothek, in der Reihenfolge seines Namens, mit dem Kopf seiner Schnittstelle: wofür es da ist, was es garantiert, und ein Beispiel. Die Module namens Bindings binden eine C-Bibliothek und sind unsicher; welches sichere Modul auf welchem steht, steht in die unsicheren Module.

Bindings.Account

Bindet das Nachschlagen eines Kontos in der Passwortdatenbank und den effektiven Benutzer des Prozesses, aus der Laufzeit.

let user: Int64 := accountNumber("_notes", false);

Bindings.Arena

Bindet die Arena der Laufzeit, die Speicher mit mmap nimmt und in Stücken ausgibt.

let made: Option[Arena] := createArena(65536);
let got: Option[Span![Int32, R]] := arenaSpan(r, 100);

Bindings.Argon2

Bindet libargon2, die Referenzimplementierung von Argon2, über Bindings.C.Argon2.

let tag: Option[String] := argon2id(asSpan(&password), asSpan(&salt), 3, 65536, 4, 32);

Bindings.Array

Bindet das Lesen und Schreiben von Zahlen in Little-Endian-Bytes, mit @embed in einfachem C.

let x: Float64 := loadFloat64(bytes, 8);

Bindings.Bcrypt

Bindet die Prüfung eines bcrypt-Hashes über die eigene Bibliothek des Systems, durch eine Funktion der Laufzeit.

let verdict: Int32 := bcryptCheck(asSpan(&password), asSpan(&stored));

Bindings.Bits

Bindet das Lesen der Bits einer Zahl als Zahl eines anderen Typs derselben Breite, in C.

let bits: Nat64 := float64Bits(1.0);

Bindings.BuildInfo

Bindet das, was der Compiler über seinen Build in das C des Programms schreibt.

let hash: Span[Nat8, Static] := commitText();

Bindings.Context

Bindet, was Standard.Context vom Kernel und von der Laufzeit braucht: Pipes und eine Kette, auf der gewartet wird.

let root: Node := emptyNode();
let ready: Int32 := nodeReady(&root, 0);
releaseNode(root);

Bindings.Database

Bindet nichts nach außen: Es hält den Wert eines Treibers in einer Box, deren Typ den Treiber nicht nennt.

let box: Erased := erase(connection);

Bindings.DuckDB

Bindet libduckdb, den Release-Build von DuckDB, über die Deklarationen von Bindings.C.Duckdb.

let opened: Either[DuckError, Connection] := connect("/var/db/stats.duckdb", false);
let changed: Either[DuckError, Nat64] := execute(&!db, "DELETE FROM hits", noValues());

Bindings.Entropy

Bindet getentropy, den Systemaufruf für ein paar Bytes sicherer Zufallszahlen, für die Schlüssel von Hash-Maps.

let seed: Nat64 := entropyWord();

Bindings.File

Bindet die Datei-, Verzeichnis-, Prozess-, Umgebungs- und Socket-Aufrufe der C-Bibliothek, über die Laufzeit.

let number: Int32 := openRead(&path);
let read: Int64 := readInto(number, &!buffer, 0, 4096);
let closed: Bool := closeNumber(number);

Bindings.Libcrypto

Bindet libcrypto über die Deklarationen in Bindings.C.Libcrypto.

let digest: Option[String] := sha256(asSpan(&message));
let sealed: Option[String] := sealAes256Gcm(asSpan(&key), asSpan(&nonce), asSpan(&text), "");

Bindings.MariaDB

Bindet libmariadb, MariaDB Connector/C, über die Deklarationen von Bindings.C.Mariadb.

let opened: Either[MariaError, Connection] := connect("db.example.org", 3306, "shop", "app",
    asSpan(&password), "/etc/ssl/cert.pem", false);
let changed: Either[MariaError, Nat64] := execute(&!db, "DELETE FROM carts", noValues());

Bindings.MlDsa

Bindet ML-DSA nach FIPS 204 aus dem libcrux-Code, den der Compiler mitführt, das Backend von Standard.MlDsa.

let made: Option[KeyBytes] := keypair(44, asSpan(&seed));

Bindings.Pcre

Bindet die 8-Bit-Bibliothek von PCRE2, libpcre2-8, über die Deklarationen in Bindings.C.Pcre2.

let compiled: Either[String, Code] := compileCode("[a-z]+", 1000000);
let found: Either[Int32, Option[Buffer[Index]]] := search(&regex, asSpan(&text), 0);

Bindings.Platform

Bindet die Namen des Systems und der Maschine, für die das Programm übersetzt wurde, und die seines Hosts, aus der Laufzeit.

let system: Span[Nat8, Static] := systemText();

Bindings.Poller

Bindet den Poller der Laufzeit, der auf viele Deskriptoren zugleich wartet.

let added: Bool := addDescriptor(&!handle, listener, 1);
let ready: Int32 := waitHandle(&!handle, 1000);
let first: Int32 := eventDescriptorAt(&handle, 0);

Bindings.Postgres

Bindet libpq, die Client-Bibliothek von PostgreSQL, über die Deklarationen von Bindings.C.Libpq.

let values: Values := withInt64(noValues(), 42);
let changed: Either[PgError, Nat64] := execute(&!db, "DELETE FROM cart WHERE id = $1", values);

Bindings.Resolve

Bindet den Resolver der C-Bibliothek, getaddrinfo, für Standard.Resolve.

let found: Either[Int32, String] := resolveRecords("example.org");

Bindings.Resource

Bindet die Ressourcenaufrufe der Laufzeit: Limits, Verbrauch und die Uhr seit dem Start.

let files: Option[LimitPair] := limitOf(1);
let raised: Bool := setLimitOf(1, 4096, 4096);

Bindings.Sandbox

Bindet die Aufrufe, die den Prozess einsperren, über die Funktionen der Laufzeit.

if platform() = 1 then
    let pledged: Int32 := pledge(&promises);
end if;

Bindings.Secret

Bindet das Lesen eines Geheimnisses vom Terminal oder einem Deskriptor, in Speicher, der gelöscht wird, bevor er zurückgegeben wird.

case allocateRaw() of
    when Some(value as raw: RawSecret) do
        destroyRaw(raw);
    when None do
        skip;
end case;

Bindings.Serial

Bindet einen Zähler, den der ganze Prozess teilt, für Zahlen, die sich nie wiederholen dürfen.

let serial: Nat64 := nextSerial();

Bindings.Shared

Bindet die Mutexe der Laufzeit und die atomaren Operationen des C-Compilers.

let { value: Nat64, key: Key } := acquire(&mutex);
release(&mutex, value + 1, key);

Bindings.Signal

Bindet die Signalbehandlung der Laufzeit, mit alarm(2), getpid(2) und kill(2).

if watchMask(7) then
    let woken: Bool := waitPipe(1000);
    let stops: Nat32 := arrivals(2);
end if;

Bindings.SqlCipher

Bindet libsqlcipher, die C-Bibliothek von SQLCipher, über die Deklarationen in Bindings.C.SqlCipher.

case openWriter("app.db", makeKey(secret)) of
    when Right(right as db: Connection) do
        closeDatabase(db);
    when Left(left as error: SqlError) do
        printLn(describe(error));
end case;

Bindings.Sqlite

Bindet libsqlite3, die C-Bibliothek von SQLite, über die Deklarationen in Bindings.C.Sqlite3.

case openWriter("app.db") of
    when Right(right as db: Connection) do
        closeDatabase(db);
    when Left(left as error: SqlError) do
        printLn(describe(error));
end case;

Bindings.SqliteReplica

Bindet libsqlite3 über die Deklarationen in Bindings.C.Sqlite3, für Anweisungen, deren Text erst beim Ausführen bekannt ist.

let opened: Either[String, Database] := openDatabase("data.db");

Bindings.SystemLog

Bindet das Systemlog, openlog(3), syslog(3) und closelog(3), über die Laufzeit.

openSystemLog("shop", 1);
writeSystemLog(1, "started");
closeSystemLog();

Bindings.Task

Bindet die Fibers, Scopes und Kanäle der Laufzeit, die Tasks auf Threads ausführen.

let started: Either[Nat64, Task[Nat64]] := spawn(&!scope, double, 21);

Bindings.Terminal

Bindet die Standardströme von libc, stdin, stdout und stderr, über die Laufzeit.

if isTerminalNumber(0) then
    let quiet: Bool := setEcho(0, false);
end if;

Bindings.Testing

Bindet, was Standard.Testing von der Laufzeit erfragt: ob das Programm unter valgrind läuft.

let underValgrind: Bool := runningUnderValgrind();

Bindings.Time

Bindet die Uhren von libc über die Laufzeit, die clock_gettime aufruft.

if hasMonotonic() then
    let now: Int64 := monotonicReading();
end if;

Bindings.Tls

Bindet libtls, die TLS-Bibliothek von OpenBSD und, als libretls über OpenSSL, von Debian.

let client: Either[String, Client] := connect("example.org", "443", "/etc/ssl/cert.pem");

Bindings.Watch

Bindet das Beobachten von Dateien in der Laufzeit: inotify auf Linux, kqueue auf den BSDs.

let watcher: Int32 := watchOpen();
let watch: Int32 := watchAdd(watcher, &path, true);
let changed: Int32 := watchWait(watcher, 5000);

Bindings.X509

Bindet die X.509- und Schlüsselfunktionen von libcrypto, die Standard.X509 braucht.

let key: Option[Key] := newKey(1);

Standard.About

Der volle Versionstext und der Infotext eines Programms, aus seinem Build und seiner Plattform.

setFullVersion(&!command, fullVersion("1.2.0", "2026 Example Corp"));

Standard.Account

Die Konten des Systems: die Nummern eines Kontos zu seinem Namen, und als wer der Prozess läuft.

case lookupAccount("_notes") of
    when AccountFound(numbers as n: AccountNumbers) do
        useOwner(n.user, n.group);
    when NoAccount do
        refuse();
    when LookupFailed do
        refuse();
end case;

Standard.Acme

Ein Client des ACME-Protokolls nach RFC 8555, mit dem eine CA Zertifikate für DNS-Namen ausstellt.

let opened: Either[AcmeError, Account] := openAccount(directory, key, "", caFile, limits);
let order: Either[AcmeError, Order] := newOrder(&!account, "example.org,www.example.org");
let challenge: Either[AcmeError, Challenge] := challengeOf(&!account, authorization, "dns-01");
let record: String := dnsChallengeValue(&!account, asSpan(&token));
let ready: Either[AcmeError, Unit] := respond(&!account, challengeUrl);

Standard.Archive

Archive in tar, tar mit gzip und zip, ganz gelesen und im Speicher geschrieben.

case readArchive(asSpan(&bytes), TarGz(), defaultBudget()) of
    when Right(right as archive: Archive) do
        let unpacked: Either[Failure, Unit] := extractArchive(&archive, "/var/www/site");
        destroyArchive(archive);
    when Left(left as failure: Failure) do
        report(failure);
end case;

Standard.Arena

Ein Bump-Allokator hinter einem linearen Handle, für den Speicher einer Arbeitseinheit wie einer Anfrage.

case createArena(65536) of
    when Some(value as made: Arena) do
        var arena: Arena := made;
        borrow r: &![Arena, R] := &!arena do
            let got: Option[Span![Int32, R]] := arenaSpan(r, 100);
        end borrow;
        arena := resetArena(arena);
        freeArena(arena);
    when None do
        abort("No memory for the arena.");
end case;

Standard.Arguments

Das Lesen der Kommandozeile eines Programms gegen ein deklariertes Kommando, seine Optionen und Unterkommandos.

var command: Command := makeCommand("fetch", "Fetches a file.");
let verbose: FlagKey := addVerbose(&!command, "Say more.");
let output: PathKey := addPath(&!command, option("output", 0, "Where to write."));
let arguments: Buffer[String] := processArguments();
let parsed: Either[ArgumentError, Outcome] := parse(&command, &arguments);

Standard.Array

Arrays von Zahlen mit Form, Strides und Elementtyp, und Views, die ihre Bytes teilen.

var a: Array := zeros(float64Type(), shape2(2, 3));
setFloat64(&!a, 4, 2.5);
let n: Index := size(&a);
destroy(a);

Standard.ArrayWire

Die Binärform eines besitzenden Arrays: ein Header mit Magic, Version, Elementtyp, Rang und Form, dann die Elemente.

let written: Index := encode(&a, &!out);
case decode(received) of
    when Right(right as b: Array) do
        destroy(b);
    when Left(left as e: DecodeError) do
        skip;
end case;

Standard.ArrayCompute

Arithmetik über Arrays: elementweise Operationen mit Broadcasting, Reduktionen über das ganze Array und entlang einer Achse, und das Zusammenführen von Teilergebnissen.

var a: Array := zeros(float64Type(), shape2(2, 3));
setFloat64(&!a, 4, 2.5);
let total: Array := sum(view(&a));
destroy(total);
destroy(a);

Standard.AtomicFile

Eine Datei so schreiben, dass jeder, der sie öffnet, den alten oder den neuen Inhalt findet, nie einen Teil davon.

let mode: Nat32 := 420;
let written: Either[AtomicFailure, Bool] := writeWithBackup("app.conf", asSpan(&text), mode);
let change: Either[AtomicFailure, Change] := writeIfChanged("app.conf", asSpan(&text), mode);

Standard.Base32

Base32 nach RFC 4648, Abschnitt 6, die Form, in der die Geheimnisse von Einmalpasswörtern geschrieben werden.

let secret: String := encodeBase32Unpadded(asSpan(&key));
let back: Option[String] := decodeBase32(asSpan(&secret));

Standard.Base64

Base64 nach RFC 4648, Abschnitt 4, mit oder ohne Padding.

let text: String := encode(asSpan(&bytes));
let back: Option[String] := decode(asSpan(&text));
let salt: Option[String] := decodeUnpadded("c2FsdHNhbHQ");

Standard.Bits

Liest die Bits einer Zahl als vorzeichenlose Zahl derselben Breite und zurück, für Formate, die Zahlen als Bytes speichern.

let one: Float64 := float64FromBits(float64Bits(1.0));

Standard.Bounded

Eine Typklasse für den kleinsten und den größten Wert eines Typs.

let top: Nat32 := maxBound();
let bottom: Int64 := minBound();

Standard.Box

Ein Wert auf dem Heap, im Besitz eines linearen Handles.

case makeBox(7) of
    when Right(right as box: Box[Nat64]) do
        let seven: Nat64 := unbox(box);
    when Left(left as value: Nat64) do
        skip;
end case;

Standard.Buffer

Ein linearer, wachsender Array auf dem Heap.

var prices: Buffer[Nat64] := allocateEmpty();
insertBack(&!prices, 250);
let first: Nat64 := nth(&prices, 0);
destroyFree(prices);

Standard.BuildInfo

Was ein Programm über seinen eigenen Build weiß: Commit, Zustand des Arbeitsbaums, Zeit, Compiler und eigene Werte.

printLn(commit());
case value("channel") of
    when Some(value as channel: Span[Nat8, Static]) do
        printLn(channel);
    when None do
        printLn("no channel");
end case;

Standard.Cache

Ein Cache für Werte unter Schlüsseln, mit einer Lebensdauer je Eintrag und Grenzen für Anzahl und Gesamtgröße.

var cache: Cache[Nat64, Nat64] := makeCache(1000, 1048576, 60000000000);
let price: Option[Nat64] := getWith(&!cache, item, nowNanos(), lookUpPrice);

Standard.Calendar

Daten und Tageszeiten im gregorianischen Kalender, Zeitzonen aus Zonendateien und RFC-3339-Text.

let zone: Either[ZoneFailure, Zone] := loadZone("Europe/Berlin");
let stamp: Option[Stamp] := parseRfc3339("2026-09-27T01:10:00+02:00");

Standard.Cbor

CBOR, wie RFC 8949 es definiert, streng in ein Dokument gelesen und Element für Element durchsucht.

case readCbor(asSpan(&coseKey)) of
    when Right(right as key: Cbor) do
        let top: CborItem := rootOf(&key);
        let entries: Option[Index] := countOf(&key, top);
        destroyCbor(key);
    when Left(left as refused: CborError) do
        printLn(refused.offset);
end case;

Standard.CompositeSig

Signiert und verifiziert mit dem Komposit aus ML-DSA-44 und Ed25519 des IETF-Entwurfs für Kompositsignaturen.

let signed: Option[String] := sign(&key, openSshLabel(), asSpan(&message), "");

Standard.Context

Abbruch und Fristen, die eine ganze Kette von Aufrufen und Tasks erreichen.

let root: Context := background();
case withTimeout(&root, 5000) of
    when Some(value as made: Derived) do
        let { context: Context, canceller: Canceller } := made;
        let budget: Nat32 := remainingMilliseconds(&context, 1000);
        cancel(canceller);
        destroyContext(context);
    when None do
        skip;
end case;
destroyContext(root);

HTTP-Cookies nach RFC 6265: ein Cookie aus einem Cookie-Header gelesen, ein Set-Cookie-Wert geschrieben.

let header: Option[String] := setCookie("session", token, "/", strictOptions());
let sent: Option[String] := cookieValue(asSpan(&cookieHeader), "session");

Standard.Cose

COSE-Schlüssel nach RFC 9052 und RFC 9053, umgewandelt in die öffentlichen DER-Schlüssel, mit denen Standard.X509 verifiziert.

case publicKeyFromCose(asSpan(&credentialKey)) of
    when Some(value as der: String) do
        let good: Bool := verifyMessage(asSpan(&der), asSpan(&signed), asSpan(&signature));
        destroyString(der);
    when None do
        printLn("not a key");
end case;

Standard.Csrf

Schutz gegen Cross-Site-Request-Forgery: ein an die Sitzung gebundenes Token und Origin-Header.

let token: Option[String] := csrfToken(serverKey, sessionToken);
if changingMethod(verb) and not csrfValid(serverKey, sessionToken, submitted) then
    refuse();
end if;

Standard.Csv

Tabellen in CSV, wie RFC 4180 sie beschreibt, gelesen und geschrieben.

case readCsv(text) of
    when Right(right as table: CsvTable) do
        let rows: Index := rowCount(&table);
        destroyCsv(table);
    when Left(left as error: CsvError) do
        report(error.line, error.offset);
end case;

Standard.Database

Eine Schnittstelle über SQLite, SQLCipher, PostgreSQL und MariaDB, das Backend beim Öffnen gewählt.

case openSqlite("app.db") of
    when Right(right as opened: Database[Writing]) do
        var db: Database[Writing] := opened;
        let values: Values := withText(withInt64(noValues(), 7), "Ada");
        case execute(&!db, "INSERT INTO people (id, name) VALUES (?, ?)", values) of
            ...
        end case;
        closeDatabase(db);
    ...
end case;

Standard.Database.MariaDB

Der MariaDB-Treiber von Standard.Database: Ein Programm, das ihn importiert, kann eine MariaDB-Verbindung öffnen.

case openMariaDB("db.example", 3306, "app", "app", password, "/etc/ssl/ca.pem") of
    when Right(right as opened: Database[Writing]) do
        ...
end case;

Standard.Database.Postgres

Der PostgreSQL-Treiber von Standard.Database: Ein Programm, das ihn importiert, kann eine PostgreSQL-Verbindung öffnen.

case openPostgres("db.example", 5432, "app", "app", password, "/etc/ssl/ca.pem") of
    when Right(right as opened: Database[Writing]) do
        ...
end case;

Standard.Database.Sqlite

Der SQLite- und SQLCipher-Treiber von Standard.Database: Ein Programm, das ihn importiert, kann diese Dateien öffnen.

case openSqlite("app.db") of
    when Right(right as opened: Database[Writing]) do
        ...
end case;

Standard.DatabaseUsers

Ein Speicher für Standard.Users in einer Datenbank von Standard.Database, auf jedem Backend, das sie hat.

case openDatabaseUsers(db) of
    when Right(right as opened: DatabaseUsers) do
        var users: DatabaseUsers := opened;
        let added: Either[UserError, Bool] := addUser(&!users, "alice", asSpan(&password));
        closeDatabase(closeDatabaseUsers(users));
    when Left(left as failed: DatabaseUsersFailed) do
        let { db: Database[Writing], error: UserError } := failed;
        closeDatabase(db);
end case;

Standard.Decimal

Dezimalzahlen für Geld: exakt, mit höchstens 18 Ziffern und höchstens 18 davon nach dem Komma.

case parseDecimal("19.99") of
    when Some(value as price: Decimal) do
        let total: Option[Decimal] := multiplyDecimal(price, quantity);
    when None do
        skip;
end case;

Standard.Doctor

Prüft, dass die Dateien, Verzeichnisse, der Socket und das Konto, die ein Programm deklariert, so vorhanden sind, wie sie sein sollen, und legt an, was fehlt.

var checkup: Checkup := makeCheckup("notes", Service());
expectPath(&!checkup, DataDirectory(), "/var/notes");
var out: StringBuilder := makeStringBuilder();
let missing: Index := runCheckup(&checkup, false, &!out);
destroyCheckup(checkup);

Standard.DuckDB

DuckDB, die Datenbank für Analyse, die innerhalb des Programms über einer eigenen Datei läuft.

case openWriter("facts.duckdb") of
    when Right(right as opened: Connection[Writing]) do
        var db: Connection[Writing] := opened;
        let values: Values := withText(withInt64(noValues(), 7), "Ada");
        case execute(&!db, "INSERT INTO people VALUES (?, ?)", values) of
            ...
        end case;
        closeDatabase(db);
    ...
end case;

Standard.Equality

Typklassen für partielle und totale Äquivalenzrelationen.

let same: Bool := equal(&left, &right);

Standard.Failure

Ein Fehlschlag für das Left eines Either: seine Operation, seine Art, seine Meldung und der Fehlschlag dahinter.

let failure: Failure := makeFailure("file.write", Unclassified(), "disk full");
let outer: Failure := wrapFailure("store.save", failure);
let line: String := describeFailure(&outer);
destroyFailure(outer);

Standard.Fcgi

Das FastCGI-Record-Protokoll von der antwortenden Seite: Records aus Bytes gelesen und zu Bytes gebaut.

case readHeader(bytes, 0) of
    when Some(value as header: RecordHeader) do
        let content: Option[String] := readContent(bytes, 0, header);
        let next: Index := recordLength(header);
    when None do
        skip;
end case;

Standard.FcgiServer

Ein FastCGI-Responder: die Schleife, die die Anfragen eines Webservers über einen Handler bedient.

function hello(request: Request): String is
    destroyRequest(request);
    return cgiResponse(200, "text/plain", "hello");
end;

let accepted: Option[Index] := serveUnix(&listener, hello, defaultLimits(), &!signals);

Standard.File

Dateien, Pipes, Verzeichnisse, Kindprozesse, die Umgebung und Sockets von Unix und TCP.

case openRead("notes.txt") of
    when Some(value as opened: FileDescriptor) do
        var file: FileDescriptor := opened;
        let text: Option[String] := readAll(&!file);
        let closed: Bool := closeFile(file);
    when None do
        skip;
end case;

Standard.FileHelpers

Helfer über Standard.File zum Kopieren, Messen, Benennen und Entfernen von Dateien und Bäumen.

case copyDirectory("site", "site-backup") of
    when Right(right as done: Unit) do
        skip;
    when Left(left as failure: Failure) do
        let line: String := describeFailure(&failure);
        destroyFailure(failure);
end case;

Standard.Graph

Ein gerichteter Graph, dessen Knoten und Kanten je einen Wert tragen.

var graph: Graph[Nat32, Nat64] := makeGraph();
let from: NodeId := addNode(&!graph, 1);
let to: NodeId := addNode(&!graph, 2);
let added: Either[Nat64, EdgeId] := addEdge(&!graph, from, to, 5);
let reached: Bool := hasPath(&graph, from, to);

Standard.Grapheme

Graphemcluster, die Zeichen, die ein Leser sieht, nach den Regeln von Unicodes Standard Annex 29.

let clusters: Option[Index] := countClusters(asSpan(&name));
let firstEnd: Option[Index] := clusterEnd(asSpan(&name), 0);

Standard.Gzip

Kompression in den Formaten von gzip: DEFLATE nach RFC 1951, roh oder in einem gzip-Member nach RFC 1952.

let packed: String := gzip(asSpan(&page));
case gunzip(asSpan(&packed), 1048576) of
    when Right(right as unpacked: String) do
        skip;
    when Left(left as failure: GzipFailure) do
        skip;
end case;

Standard.Hash

Schlüsselbasiertes Hashing mit SipHash und die Typklasse Hashable, die eine Hash-Map von ihren Schlüsseln braucht.

let tag: Nat64 := sipHash24(key0, key1, asSpan(&message));
let slot: Nat64 := hashOf(&name, key0, key1);

Standard.HashMap

Eine Hash-Map, deren Schlüssel mit SipHash-1-3 unter einem eigenen Schlüssel gehasht werden.

var ages: HashMap[Nat64, Nat32] := makeHashMap();
let replaced: Option[Pair[Nat64, Nat32]] := put(&!ages, id, 36);
let age: Option[Nat32] := get(&ages, &id);
destroyFree(ages);

Standard.Html

HTML nach dem Tokenizer des HTML-Standards in Tokens gelesen, sein Text herausgezogen oder bereinigt.

let clean: String := sanitize(asSpan(&comment), basicPolicy());
let plain: String := textOf(asSpan(&page));

Standard.Htmx

Die Serverseite von htmx: seine Anfragen unterschieden, seine Antwort-Header geschrieben, sein Skript ausgeliefert.

if isHtmxRequest(asSpan(&hxRequest)) then
    let line: String := redirectHeader("/done");
    let answer: String := htmlResponse(200, asSpan(&line), "");
end if;

Standard.Http

Fragen an einen HTTP-Header-Block, beantwortet aus dem Text des Blocks, wie er steht.

let length: Option[String] := headerValue(asSpan(&headers), "Content-Length");
let upgrade: Bool := valueHasToken(asSpan(&connection), "upgrade");

Standard.HttpClient

Ein HTTPS-Client: eine Anfrage, eine Antwort, dann wird die Verbindung geschlossen.

let answer: Either[Failure, Response] :=
    request(Get(), "https://example.org/status", "", "", "/etc/ssl/cert.pem", defaultLimits());

Standard.I18n

Übersetzte Texte aus einem Katalog, der Teil des Programms ist, für Templates und für Code.

var arguments: Arguments := makeArguments();
addText(&!arguments, "name", "Ada");
let greeting: String := translate(messages(), "de", Greeting(), None(), &arguments);
destroyArguments(arguments);

Standard.IO

Die Capability für den Zugang zum Terminal und die Typklassen für Byte-Ströme.

var terminal: TerminalCapability := acquireTerminal(&!root);
var output: StandardOutput := acquireOutput(&!terminal);
writeByte(&!output, 10);
releaseOutput(output);
releaseTerminal(terminal);

Standard.IO.Terminal

Die Standardausgabe, die Standardfehlerausgabe und die Standardeingabe eines Programms.

var terminal: TerminalCapability := acquireTerminal(&!root);
var input: StandardInput := acquireInput(&!terminal);
let line: String := readLine(&!input);
releaseInput(input);
releaseTerminal(terminal);

Standard.Ini

Konfigurationsdateien in der INI-Form: Zeilen der Art name = wert, gruppiert unter [section]-Köpfen.

let file: IniFile := readIni(asSpan(&text));
let defaults: IniFile := readIni(asSpan(&shipped));
let port: Option[String] := iniValueWith(&file, &defaults, "server", "port");
let verbose: Bool := iniSwitch(&file, "log", "verbose");
destroyIni(defaults);
destroyIni(file);

Standard.Ip

IP-Adressen, IPv4 und IPv6: parsen, ausgeben, maskieren, abgleichen und anonymisieren.

case parseIp(asSpan(&peer)) of
    when Some(value as address: IpAddress) do
        let inside: Bool := inSubnet(address, office, 24);
        let logged: String := ipToString(anonymise(address));
    when None do
        printLn("not an address");
end case;

Standard.Json

JSON nach der Definition von RFC 8259, streng in ein Dokument gelesen und über einen Writer geschrieben.

var writer: JsonWriter := makeJsonWriter();
beginObject(&!writer);
writeName(&!writer, "id");
writeInteger(&!writer, 42);
endObject(&!writer);
let text: Option[String] := finishJson(writer);

case readJson(asSpan(&body)) of
    when Right(right as document: Json) do
        let id: Option[Int64] := integerAt(&document, "/id");
        destroyJson(document);
    when Left(left as refused: JsonError) do
        printLn(refused.offset);
end case;

Standard.Jws

JSON Web Signatures in der kompakten Form von RFC 7515, JSON Web Keys und OpenID-Connect-Claims.

case verifyWithJwks(asSpan(&token), asSpan(&keySet)) of
    when Some(value as payload: String) do
        let problem: Option[String] :=
            claimsProblem(asSpan(&payload), issuer, clientId, asSpan(&nonce), now, 60);
    when None do
        printLn("token refused");
end case;

Standard.Libcrypto

Authentifizierte Verschlüsselung, Schlüsselvereinbarung, Signaturen, Hashes und sichere Zufallsbytes.

case randomBytes(12) of
    when Some(value as nonce: String) do
        let sealed: Option[String] :=
            sealChaCha20Poly1305(asSpan(&key), asSpan(&nonce), asSpan(&message), "");
        destroyString(nonce);
    when None do
        printLn("no random bytes");
end case;

Standard.Log

Log-Einträge mit einer Stufe, einer Nachricht und benannten Feldern, je eine Zeile.

var log: Log := logToError(acquireError(&!terminal), Info(), TextLines());
let entry: Entry := addInteger(makeEntry(Warning(), "slow request"), "millis", millis);
let written: Bool := writeEntry(&!log, entry);
let closed: Bool := closeLog(log);

Standard.Map

Eine Map von Schlüsseln auf Werte, geordnet nach der TotalOrder der Schlüssel aus Standard.Order.

var stock: Map[Nat64, Nat64] := makeMap();
let old: Option[Pair[Nat64, Nat64]] := put(&!stock, item, 12);
let count: Option[Nat64] := get(&stock, &item);
destroyFree(stock);

Standard.MariaDB

Ein Client für MariaDB über die libmariadb des Systems, in der Form von Standard.Postgres.

case openWriter("db.local", 3306, "shop", "app", asSpan(&password), "ca.pem") of
    when Right(right as db: Connection[Writing]) do
        let values: Values := withText(withInt64(noValues(), 7), "apple");
        let changed: Either[MariaError, Nat64] :=
            execute(&!db, "insert into stock (id, name) values (?, ?)", values);
        closeDatabase(db);
    when Left(left as failed: MariaError) do
        printLn(describe(failed));
end case;

Standard.MlDsa

Signiert und verifiziert mit ML-DSA nach FIPS 204 auf den Stufen 44, 65 und 87.

let key: Option[MlDsaKey] := generateKeyPair(Level44());

Standard.Normalization

Die vier Normalisierungsformen von Unicode für UTF-8-Text, NFD, NFC, NFKD und NFKC.

case toNfc(asSpan(&typed)) of
    when Some(value as normal: String) do
        printLn(asSpan(&normal));
        destroyString(normal);
    when None do
        printLn("not UTF-8");
end case;

Standard.Order

Typklassen für Halb- und Totalordnungen, mit den Totalordnungen von Integers und Strings.

case compare(&left, &right) of
    when LessThan do
        printLn("before");
    when Equal do
        printLn("same");
    when GreaterThan do
        printLn("after");
end case;

Standard.Otp

Einmalpasswörter, HOTP nach RFC 4226 und TOTP nach RFC 6238, wie Authenticator-Apps sie erzeugen.

let accepted: Bool :=
    verifyTotp(asSpan(&secret), asSpan(&code), nowSeconds, 30, 6, OtpSha1(), 1);

Standard.Password

Passwörter, als Argon2id-Hashes in der PHC-String-Form gespeichert und dagegen geprüft.

let stored: Option[String] := hashPassword(asSpan(&typed));
let check: PasswordCheck := checkPassword(asSpan(&typed), asSpan(&saved));

Standard.Path

Einen Pfad zerlegen und zusammensetzen, als Text.

if hasParentComponent(asSpan(&upload)) then
    printLn("refused");
else
    let target: String := joinPath("/var/spool/in", asSpan(&upload));
    let suffix: Option[String] := extension(asSpan(&target));
end if;

Standard.Paths

Wo ein Dienst oder ein Benutzerwerkzeug auf jedem System seine Konfiguration, Geheimnisse, Daten, Logs und seinen Socket ablegt.

case choosePath("notes", Service(), PepperFile(), flag, configured) of
    when Some(value as path: String) do
        usePepper(asSpan(&path));
    when None do
        refuse();
end case;

Standard.Pcre

Reguläre Ausdrücke über PCRE2, mit dessen Syntax und dessen Engine.

case compile("([a-z]+)@([a-z.]+)", 100000) of
    when Right(right as regex: Regex) do
        let hits: Either[String, Buffer[Hit]] := find_all(&regex, asSpan(&text));
        destroyRegex(regex);
    when Left(left as message: String) do
        printLn(asSpan(&message));
end case;

Standard.PcreJit

Muster von Standard.Pcre, vom JIT von PCRE2 zu Maschinencode kompiliert.

case compile("[0-9]{4}-[0-9]{2}-[0-9]{2}", 100000) of
    when Right(right as compiled: Compiled) do
        let { regex: Regex, fallBack: Option[String] } := compiled;
        let found: Either[String, Bool] := match(&regex, asSpan(&line));
        destroyRegex(regex);
    when Left(left as message: String) do
        printLn(asSpan(&message));
end case;

Standard.Platform

Das System und die Maschine, für die das Programm kompiliert wurde, und der Host, auf dem es läuft.

print(systemName());
print("/");
printLn(machineName());

Standard.Png

PNG-Bilder mit 8 Bit pro Kanal, geschrieben und gelesen.

case decodePng(asSpan(&data), 4194304) of
    when Right(right as image: Image) do
        let file: String := encodePng(&image);
        destroyImage(image);
    when Left(left as error: PngError) do
        reportBadImage(error);
end case;

Standard.Poller

Auf viele Deskriptoren gleichzeitig warten.

case createPoller() of
    when Some(value as made: Poller) do
        var poller: Poller := made;
        let watched: Bool := watchFile(&!poller, &socket, interestRead);
        let ready: Option[Index] := waitFor(&!poller, 1000);
        let first: Option[Event] := nthEvent(&poller, 0);
        destroyPoller(poller);
    when None do
        useBlockingReads();
end case;

Standard.Postgres

PostgreSQL über die libpq des Systems, mit den Typen und der Form von Standard.Sqlite.

case openWriter(host, 5432, "app", "app", asSpan(&password), caFile) of
    when Right(right as made: Connection[Writing]) do
        var db: Connection[Writing] := made;
        let values: Values := withText(withInt64(noValues(), 42), "Ada");
        let insert: Span[Nat8, Static] := "INSERT INTO people (id, name) VALUES ($1, $2)";
        let changed: Either[PgError, Nat64] := execute(&!db, insert, values);
        closeDatabase(db);
    when Left(left as error: PgError) do
        logLine(describe(error));
end case;

Standard.Qr

QR-Codes nach ISO/IEC 18004, Modell 2, aus Text in Hilde erzeugt.

case encodeQr("https://example.org/ticket/4711", QrMedium()) of
    when Some(value as code: QrCode) do
        let image: Option[Image] := qrToImage(&code, 8, 4);
        destroyQr(code);
        showImage(image);
    when None do
        reportTooLong();
end case;

Standard.Raft

Raft-Konsens als eigene Zustandsmaschine: Nachrichten und Ticks gehen hinein, Nachrichten und festgeschriebene Einträge kommen heraus.

var node: Node := newNode(Config(id => 1, electionTicks => 10, heartbeatTicks => 2, seed => 7, quorum => majority), members);
tick(&!node);
let outgoing: Buffer[Message] := takeMessages(&!node);

Standard.RaftTcp

Die Nachrichten von Standard.Raft über TCP: jede als Bytes hinter einer Länge von vier Bytes.

let sent: Bool := sendMessage(&!socket, &message);
let next: Option[Message] := receiveMessage(&!socket);

Standard.Regex

Reguläre Ausdrücke in linearer Zeit.

case compile("^[0-9]+-[0-9]+$") of
    when Right(right as regex: Regex) do
        let isRange: Bool := match(&regex, asSpan(&text));
        destroyRegex(regex);
    when Left(left as message: String) do
        reportPattern(message);
end case;

Standard.Resolve

Hostnamen, über die Hosts-Datei und DNS zu Adressen aufgelöst, so wie das System sie einrichtet.

case resolveHost("mail.example.org", AnyFamily()) of
    when Right(right as addresses: Buffer[IpAddress]) do
        connectToFirst(addresses);
    when Left(left as failure: ResolveFailure) do
        reportFailure(failure);
end case;

Standard.Resource

Die Ressourcenlimits des Prozesses, was er verbraucht hat, und wie lange das System läuft.

let cores: Bool := disableCoreDumps();
case readLimit(OpenFiles()) of
    when Some(value as limit: Limit) do
        let wide: Limit := Limit(soft => limit.hard, hard => limit.hard);
        let raised: Bool := setLimit(OpenFiles(), wide);
    when None do
        skip;
end case;

Standard.Sandbox

Beschränkt den laufenden Prozess auf das, was eine Policy erlaubt, und sagt, was ihn wirklich beschränkt.

let promised: Policy := allowPromises(makePolicy(), "stdio rpath inet");
let policy: Policy := allowPath(promised, "/var/www", "r");
let report: Report := applyPolicy(policy);
printLine(describeReport(report));

Volltextsuche in einer Datenbank von Standard.Database, mit dem FTS5-Modul von SQLite.

case search(&!db, asSpan(&typed), 10, 0, "<mark>", "</mark>") of
    when Right(right as hits: Buffer[SearchHit]) do
        renderHits(&hits);
        destroyHits(hits);
    when Left(left as error: SearchError) do
        showNoResults(error);
end case;

Standard.Secret

Passwörter und andere Geheimnisse, ohne Echo vom Terminal gelesen und in Speicher gehalten, der gelöscht wird, wenn sie gehen.

case readNewSecret("New password: ", "Again: ") of
    when Right(right as secret: Secret) do
        store(secretBytes(&secret));
        destroySecret(secret);
    when Left(left as error: SecretError) do
        refuse(error);
end case;

Standard.Semver

Release-Versionen der Form vX.Y.Z, wie Git-Tags sie tragen, gelesen, geschrieben und geordnet.

case parseVersion("v1.4.2") of
    when Some(value as version: Version) do
        let text: String := formatVersion(version);
        printLn(asSpan(&text));

Standard.Session

Serverseitige Sessions in einer Datenbank von Standard.Database, mit einem Leerlauf- und einem absoluten Zeitlimit.

let limits: SessionLimits := defaultSessionLimits();
case loadSession(&!db, asSpan(&cookieToken), limits, now) of
    when Right(right as found: Option[String]) do
        serveWith(found);
    when Left(left as error: SessionError) do
        reportFailure(error);
end case;

Standard.Setup

Die Unterbefehle setup und user eines Programms: sein Vault für Geheimnisse, seine Completion und sein Handbuch, und seine Benutzer.

let setup: SetupKeys := addSetup(&!root);
case parse(&root, &arguments) of
    when Right(right as outcome: Outcome) do
        useOutcome(outcome);
    when Left(left as error: ArgumentError) do
        useError(error);
end case;

Standard.Sftp

SFTP Version 3 über die Pipes eines Kindprozesses.

case startSession(command, 30000) of
    when Some(value as opened: Session) do
        var session: Session := opened;
        let content: Either[SftpError, String] := readFile(&!session, "/srv/data/report.csv");
        let status: ProcessStatus := endSession(session);
        store(content);
    when None do
        reportNoServer();
end case;

Standard.Shared

Zustand, den Tasks gemeinsam nutzen: ein Mutex, der einen Wert schützt, und ein atomares Wort mit 64 Bit.

let { value as count: Int64, key: Key } := acquire(counter);
release(counter, count + 1, key);
let total: Int64 := atomicAdd(requests, 1);

Standard.SharedCache

Ein Standard.Cache, den Tasks gemeinsam nutzen, mit einer Befüllung je Schlüssel.

case makeSharedCache(1000, 1048576, 60000000000) of
    when Some(value as cache: SharedCache[Nat64, Nat64]) do
        servePrices(cache);
    when None do
        reportNoMemory();
end case;

let price: Option[Nat64] := getWith(prices, item, nowNanos(), lookUpPrice);

Standard.Signal

Signale als Ereignisse, eine Zeitgrenze für das Herunterfahren und PID-Dateien.

let wanted: Wanted := Wanted(hangup => true, interrupt => true, terminate => true,
                             user1 => false, user2 => false);
case watchSignals(wanted) of
    when Some(value as watch: Signals) do
        var signals: Signals := watch;
        while not shutdownRequested(&!signals) do
            let woken: Bool := waitSignal(&!signals, 1000);
        end while;
        let left: Nat32 := limitShutdown(10);
        let restored: Bool := stopWatching(signals);
    when None do
        reportNoWatch();
end case;

Standard.Signify

Schlüssel und Signaturen in den Dateien von signify(1) aus OpenBSD: Ed25519, base64, eine Kommentarzeile.

case generateKeys("demo") of
    when Some(value as keys: KeyPair) do
        let { publicKey: String, secretKey: String } := keys;
        case signMessage(asSpan(&secretKey), "text", "verify with demo.pub") of
            when Some(value as signature: String) do
                let good: Bool := verifyMessage(asSpan(&publicKey), "text", asSpan(&signature));

Standard.Smtp

Mail über ein Relay versenden, im Dialog nach RFC 5321 über TLS, mit einfachen Nachrichten nach RFC 5322.

case makeRelay("mail.example.org", 587, StartTls(), "/etc/ssl/cert.pem", 30000) of
    when Some(value as relay: Relay) do
        let sent: Either[MailFailure, Unit] := sendMail(&relay, "app", asSpan(&password),
                                                        &envelope, asSpan(&message));
        reportMail(sent);
        destroyRelay(relay);
    when None do
        reportBadHost();
end case;

Standard.Sort

Sortieren und Suchen in einem Buffer, dessen Elemente eine totale Ordnung nach Standard.Order.TotalOrder haben.

let sorted: Buffer[String] := sort(names);
case binarySearch(&sorted, &wanted) of
    when Found(position: Index) do
        showAt(position);
    when Missing(insertAt: Index) do
        offerToAdd(insertAt);
end case;

Standard.Sperli

Ein Job aus Rängen, die einander Nachrichten über TLS 1.3 senden, mit der Semantik des Nachrichtenaustauschs und ohne dessen Schnittstelle.

let started: Either[Int32, Comm] := init(job);
let sent: Int32 := send(&!comm, 1, 7, message);
let arrived: Int32 := barrier(&!comm);

Standard.SperliCkpt

Die Dateien und Frame-Nutzdaten eines Sperli-Checkpoints: Rang-Dateien, signierte COMMIT-Dateien und ihr Ort auf der Platte.

let file: Option[String] := rankFile(job, 1, 0, 2, asSpan(&state));
let verdict: Int32 := checkCommit(asSpan(&commit), publicKey, job, 1, 2);

Standard.SperliCollective

Die Bytes der kollektiven Frames von Sperli und die Reduktion zweier Zahlen-Arrays.

let payload: String := collectivePayload(bcastOperation(), bytesType(), noReduction(), resultPhase(), 0, 1, "data");
let verdict: Int32 := checkCollective(asSpan(&payload), bcastOperation(), bytesType(), noReduction(), resultPhase(), 0, 1);

Standard.SperliError

Die Codes, mit denen ein Sperli-Job eine Gegenstelle, einen Frame oder ein Token ablehnt, und ihre Worte.

let why: Span[Nat8, Static] := describe(badToken());

Standard.SperliExport

Die Aufrufe von Standard.Sperli in der Form, die eine C-Bibliothek exportieren kann: eine Session, die das Comm und das letzte Ergebnis hält, und Codes statt Either.

let session: Session := openSession(text);
let sent: Int32 := sessionSend(&!session, 1, 7, message);

Standard.SperliLaunch

Der Launcher eines Sperli-Jobs: liest die Hostliste, erzeugt die Schlüssel und Zertifikate des Jobs und startet die Ränge.

let hosts: Either[Int32, HostList] := parseHostList(text, "");

Standard.SperliWire

Die Bytes von Sperli, der Cluster-Schicht: Frame-Header, Hello-Nutzdaten und Join-Tokens.

let header: String := frameHeader(dataKind(), 5, job, 1, 0, 0, 1, 7);
let verdict: Int32 := checkHeader(asSpan(&header), job, 1, 1, 0);

Standard.SqlCipher

SQLCipher über die libsqlcipher des Systems: Standard.Sqlite mit verschlüsselter Datenbankdatei.

case openWriter("app.db", makeKey(secret)) of
    when Right(right as db: Connection[Writing]) do
        closeDatabase(db);
    when Left(left as error: SqlError) do
        printLn(describe(error));
end case;

Standard.Sqlite

SQLite über die libsqlite3 des Systems, mit jeder Abfrage zur Übersetzungszeit gegen das Schema geprüft.

@query(&!db, "SELECT id, name FROM users WHERE age > ?", age)
    for row: User[R] do
        printLn(row.name);
    else error do
        printLn(describe(error));
    end for;

Standard.SqliteReplica

SQLite, über Standard.Raft repliziert: Jeder Schreibzugriff ist ein Eintrag des Logs, den jeder Knoten in derselben Reihenfolge anwendet.

case proposeWrite(&!node, &store, "INSERT INTO kv (k, v) VALUES (?, ?)", &values) of
    when Right(right as index: Nat64) do
        skip;
    when Left(left as refusal: Nat8) do
        skip;
end case;

Standard.SqliteUsers

Ein Store für Standard.Users in einer SQLite-Datenbank von Standard.Sqlite.

case openSqliteUsers(db) of
    when Right(right as opened: SqliteUsers) do
        var users: SqliteUsers := opened;
        let added: Either[UserError, Bool] := addUser(&!users, "alice", asSpan(&password));
        closeDatabase(closeSqliteUsers(users));
    when Left(left as failed: SqliteUsersFailed) do
        let { db: Connection[Writing], error: UserError } := failed;
        closeDatabase(db);
end case;

Standard.Ssh

Befehle, die der ssh-Client von OpenSSH auf einem anderen Host ausführt, und jedes Kind, das in begrenzter Zeit und Größe läuft.

case sshCommand("/usr/bin/ssh", "backup.example.org", "deploy", 22, 10) of
    when Right(right as base: Command) do
        let command: Command := addRemoteWord(addRemoteWord(base, "df"), "-h");
        case runCommand(command, 30000, 65536) of
            when Right(right as result: CommandResult) do
                showResult(result);
            when Left(left as error: SshError) do
                reportFailure(error);
        end case;
    when Left(left as error: SshError) do
        reportFailure(error);
end case;

Standard.String

Der Typ String, eine lineare Byte-Zeichenkette auf dem Heap, der ihre Bytes gehören.

var line: String := fromLiteral("hello, world");
storeNth(&!line, 0, 72);
let head: String := fromSpan(getSpan(&line, 0, 4));
let size: Index := length(&line);
destroyString(head);
destroyString(line);

Standard.StringBuilder

Ein Builder, der Bytes an seinem Ende sammelt und als einen String übergibt.

var builder: StringBuilder := makeStringBuilder();
writeString(&!builder, "id=");
writeByte(&!builder, 52);
let line: String := finalize(builder);

Standard.Task

Strukturierte Nebenläufigkeit: Tasks, die zu einem Scope gehören, und Kanäle mit zwei linearen Enden.

var scope: Scope := opened;
case spawn(&!scope, work, 21) of
    when Right(right as task: Task[Int32]) do
        printLn(join(task));
    when Left(left as unused: Int32) do
        printLn(-1);
end case;
closeScope(scope);

Standard.TaskArena

Ein Task, dem eine eigene Arena übergeben wird, die mit dem Task endet.

case spawnWithArena(&!scope, work, request, 65536) of
    when Right(right as task: Task[Reply]) do
        answer(join(task));
    when Left(left as unused: Request) do
        refuse(unused);
end case;

Standard.Template

Jinja2-Templates, beim Übersetzen des Programms geprüft, und was ihr erzeugter Code aufruft.

var out: StringBuilder := makeStringBuilder();
@template("page.jinja", page, out);
return finalize(out);

Standard.Testing

Assertions für Tests, die hilde test ausführt.

assertTrue(isLeapYear(2024), "2024 is a leap year");
assertFalse(isLeapYear(1900), "1900, divided by 100 but not by 400, is not");

Standard.Text

Was man mit Text tut: ihn parsen, kodieren, vergleichen und zerlegen.

let port: Option[Nat64] := parseNat(trim(asSpan(&field)));
let parts: Buffer[Span[Nat8, Static]] := split("a,b,c", ",");

Standard.Time

Eine Wanduhr, die sagt, wie spät es ist, und eine monotone Uhr, die sagt, wie viel Zeit vergangen ist.

let stamp: Nat64 := wallNanos();
case monotonicNanos() of
    when Some(value as start: Nat64) do
        work();
        report(start);
    when None do
        work();
end case;

Standard.Tls

Ein TLS-Client und -Server, über libtls auf OpenBSD und libretls auf Debian.

let made: Either[String, Client] := connect("example.org", "443", "/etc/ssl/cert.pem");
let sent: Either[String, Unit] := send(&!client, asSpan(&request));

Standard.Toml

TOML, wie Version 1.0.0 seiner Spezifikation es definiert, streng gelesen und dann per Pfad abgefragt.

case readToml(asSpan(&text)) of
    when Right(right as parsed: Toml) do
        let port: Option[Int64] := integerAt(&parsed, "servers[1].port");
        destroyToml(parsed);
    when Left(left as error: TomlError) do
        report(error.line, error.column);
end case;

Standard.Tuples

Records aus zwei bis sechs Werten beliebiger Typen, mit Feldern, die nach ihrer Position benannt sind.

let old: Pair[String, Nat64] := Pair(first => word, second => seen);
let { first: String, second: Nat64 } := old;

Standard.Unicode

Groß- und Kleinschreibung von UTF-8-Text und Vergleich ohne Rücksicht auf die Schreibung.

let shout: Option[String] := toUpper("Gruesse aus Koeln");
let same: Bool := equalIgnoringCase("STRASSE", asSpan(&street));

Standard.UnicodeProperties

Eigenschaften von Codepunkten aus der Unicode Character Database, Version 17.0.0.

let category: Span[Nat8, Static] := generalCategory(65);
var ranges: Buffer[Index] := allocateEmpty();
let known: Bool := appendProperty("Greek", &!ranges);

Standard.Users

Benutzerkonten mit Argon2id-Passwörtern, Sperren und einer Grenze für fehlgeschlagene Versuche, über einen Store, den das Programm wählt.

case verify(&!users, "alice", asSpan(&typed), asSpan(&address), limits, now) of
    when Right(right as verdict: Verdict) do
        answer(verdict);
    when Left(left as error: UserError) do
        reportFailure(error);
end case;

Standard.Utf8

UTF-8: es dekodieren, validieren und bauen.

case makeCodePoint(233) of
    when Some(value as point: CodePoint) do
        appendCodePoint(&!builder, point);
    when None do
        skip;
end case;
let count: Option[Index] := countCodePoints(asSpan(&text));

Standard.Vault

Verschlüsselte Geheimnisse in einer .env-Datei, lesbar nur mit dem Schlüssel in dieser Datei und einem Pepper in einer eigenen Datei.

case openVault("/etc/app/secret/.app.env", "/var/lib/app/.app.pepper", "VAULT_KEY") of
    when Right(right as opened: Vault) do
        var vault: Vault := opened;
        let stored: Either[VaultError, Unit] := setSecret(&!vault, "DB_PASSWORD", "s3cret");
        closeVault(vault);
    when Left(left as error: VaultError) do
        skip;
end case;

Standard.Watch

Dateien und Verzeichnisse auf Änderungen beobachten: inotify auf Linux, kqueue auf OpenBSD und FreeBSD.

var watcher: Watcher := made;
let config: Option[Index] := watchFile(&!watcher, "/etc/app.conf");
case waitForChange(&!watcher, 5000) of
    when Changed(watch as changed: Index) do
        reload();
    when WaitedOut do
        skip;
    when WatchFailed do
        skip;
end case;
destroyWatcher(watcher);

Standard.X509

Schlüssel und X.509-Zertifikate: erzeugt, geschrieben, gelesen, signiert und geprüft.

let key: Option[PrivateKey] := generateKey(EcP256());
let made: Option[Certificate] := selfSigned(&signer, "web", "example.org", 90, false);

Standard.Xml

XML 1.0, in Tokens gelesen, ohne Dokumenttyp, und dafür maskierter Text.

case parseXml(asSpan(&text)) of
    when Right(right as parsed: XmlDocument) do
        let feed: Option[Index] := xmlFindStart(&parsed, 0, "feed");
        destroyXmlDocument(parsed);
    when Left(left as error: XmlError) do
        report(error.offset);
end case;

Standard.Yaml

Der Teil von YAML, den Konfigurationsdateien verwenden, in die Werte von Standard.Json gelesen.

case readYaml(asSpan(&text)) of
    when Right(right as config: Json) do
        apply(config);
    when Left(left as error: YamlError) do
        report(error.line);
end case;