Lyricdev
GitHub

std.codec

Serializes values in any format: Encode writes a value into an Encoder, Decode reads one out of a Decoder, and Codable is both. A format — std.json, std.toml — is an encoder and a decoder of its own; this module holds the pair, the container model the formats implement, the errors (DecodeError, EncodeError), the conformances of the core types, the @Codec attribute that steers the synthesized conformances, and Value, a tree of the ten forms that any format could write — the format of no format, for tests and for data that is passed on unread.

std.encoding is a different module: it turns bytes into text and back (Base64, hexadecimal); this one writes the form of a value, in whatever format.

The model has ten forms: null, bool, int, uint, float, string, bytes, a sequence, a map, a struct of named fields, and a variant of an enum with or without a payload. A format implements the primitives of Encoder and Decoder — the scalars, and begin/end around the containers —; over them lies the layer a conformance writes with: e.field("id", this.id) encodes a field, d.field<int>("id") decodes one, e.element(x) and d.next<T>() an element. An encoder or a decoder is passed by reference, &e, as a hasher is: a conformance is generic over the format's type, and the format keeps its state.

Examples

import std.io { println };
import std.codec { Codable, Codec, EncodeError };
import std.json;

@Codec { rename = .SnakeCase }
struct Account :: [Codable] {
    userName: string,
    @Codec { skip = true }
    token: ?string,
}

fn main(): void throws EncodeError {
    println(try json.encode(Account { userName = "ada", token = "secret" }));
}
{"user_name":"ada"}

Types

Case enum — Selects how a field name is rewritten on the wire: as written, camelCase, or snake_case.
Codec struct — Steers the synthesized encode and decode.
Encode interface — A value that writes itself into any encoder.
Decode interface — A value that reads itself out of any decoder.
Codable interface — A value that is both Encode and Decode: what std.json.encode takes and std.json.decode<T> gives.
DecodeErrorKind enum — Classifies why a value could not be read: what was missing, mismatched, invalid or unknown.
DecodeError struct — The error a decoder throws: what was wrong, where in the data — users[0].mail, "" at the root — and the detail.
EncodeError struct — The error an encoder throws: a format that cannot hold the form — a map keyed by a struct in JSON — or a writer that failed (then cause() is its error), at a path in the value.
Encoder interface — The writing side of a format: the scalars, and the containers as begin/end around their parts.
Decoder interface — The reading side of a format, pull-based: a conformance asks for the form it expects, and the format answers it or throws TypeMismatch.
Bytes struct — Bytes in the format's own byte form: what encodeBytes/decodeBytes carry — Base64 in JSON, an array of numbers in TOML, the bytes themselves in a binary format.
Value enum — A tree of the ten forms: what any encoder is given and any decoder answers, as a value.
ValueEncoder class — An encoder that builds a Value: Value.encoder(), then v.encode(&e), then e.value().
ValueDecoder class — A decoder that reads a Value: tree.read<T>(), or tree.decoder() for one to pass on.

Functions

pub fn wireName(f: FieldInfo, own: ?Codec, type: ?Codec): string

Returns the name a field is written under: its own @Codec { name } where set, else its name under the type's rename.

pub fn snakeCase(name: string): string

Returns name in snake case: userId as user_id. Every uppercase character becomes _ and its lowercase form.

pub fn camelCase(name: string): string

Returns name in camel case: user_id as userId. Every _ is dropped and the character after it is uppercased.

pub fn variantNames<E>(): string[]

Returns the names of E's variants, in declaration order.

Extensions

extend<E :: [Encoder]> E
pub mut fn element<T :: [Encode]>(v: T): void throws EncodeError

Encodes v as the next element of the sequence begun.

Errors

Throws what encoding v throws.

pub mut fn entry<K :: [Encode], V :: [Encode]>(k: K, v: V): void throws EncodeError

Encodes the key k and the value v as the next entry of the map begun.

Errors

Throws EncodeError where the format cannot hold the key, or what encoding either throws.

pub mut fn field<T :: [Encode]>(name: string, v: T): void throws EncodeError

Encodes v as the field name of the struct begun.

Errors

Throws what encoding v throws.

pub mut fn encodeUnitVariant(
    enumName: string,
    variant: string,
    index: int
): void throws EncodeError

Encodes a unit variant whole: beginVariant without a payload, then endVariant.

Errors

Throws what the encoder throws.

pub mut fn encodeVariant<T :: [Encode]>(
    enumName: string,
    variant: string,
    index: int,
    payload: T
): void throws EncodeError

Encodes a variant whole, with payload between beginVariant and endVariant.

Errors

Throws what the encoder or encoding payload throws.

extend<D :: [Decoder]> D
pub mut fn next<T :: [Decode]>(): ?T throws DecodeError

Decodes the next element of the sequence begun; returns null at its end.

Errors

Throws what decoding the element throws.

pub mut fn nextKey<K :: [Decode]>(): ?K throws DecodeError

Decodes the next key of the map begun; returns null at its end. value<V>() reads its value.

Errors

Throws what decoding the key throws.

pub mut fn value<V :: [Decode]>(): V throws DecodeError

Decodes the value of the key read last.

Errors

Throws what decoding the value throws.

pub mut fn field<T :: [Decode]>(name: string): T throws DecodeError

Decodes the field name of the struct begun, which the data must have.

Errors

Throws DecodeError of kind Missing where the data lacks the field, or what decoding its value throws.

pub mut fn optional<T :: [Decode]>(name: string): ?T throws DecodeError

Decodes the field name of the struct begun, which the data may lack; returns null for a missing field, as for a null in the data.

Errors

Throws what decoding the value throws.

pub mut fn decodeNullable<T :: [Decode]>(): ?T throws DecodeError

Decodes a value that may be null: returns null for a null, the decoded value else.

Errors

Throws what decoding the value throws.

pub mut fn element<T :: [Decode]>(): T throws DecodeError

Decodes the next element of the sequence begun, which must be there.

Errors

Throws DecodeError of kind Missing at the end of the sequence, or what decoding the element throws.

pub mut fn payload<T :: [Decode]>(): T throws DecodeError

Decodes the payload of the variant begun.

Errors

Throws what decoding the payload throws.

pub mut fn fieldOrAbsent<T :: [Decode]>(
    name: string,
    skipped: bool = false
): T throws DecodeError

Decodes a field as the synthesized decode reads it: the value where the data has it, else what decodeAbsent gives — null for an optional. A skipped field is never read.

Errors

Throws DecodeError of kind Missing for an absent non-optional field, or what decoding the value throws.

extend bool :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): bool throws DecodeError
extend int :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): int throws DecodeError
extend int8 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): int8 throws DecodeError
extend int16 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): int16 throws DecodeError
extend int32 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): int32 throws DecodeError
extend uint8 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): uint8 throws DecodeError
extend uint16 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): uint16 throws DecodeError
extend uint32 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): uint32 throws DecodeError
extend uint :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): uint throws DecodeError
extend float :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): float throws DecodeError
extend float32 :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): float32 throws DecodeError
extend string :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): string throws DecodeError
extend char :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): char throws DecodeError
extend Instant :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): Instant throws DecodeError
extend Duration :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): Duration throws DecodeError
extend Date :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): Date throws DecodeError
extend Time :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): Time throws DecodeError
extend DateTime :: [Codable]

Conforms to Codable.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
static fn decode<D :: [Decoder]>(&d: D): DateTime throws DecodeError
extend<T :: [Encode]> ?T :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T :: [Decode]> ?T :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): ?T throws DecodeError
static fn decodeAbsent<D :: [Decoder]>(&d: D, name: string): ?T throws DecodeError
extend<T :: [Encode]> T[] :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T :: [Decode]> T[] :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): T[] throws DecodeError
extend<T :: [Encode]> Slice<T> :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T :: [Encode]> List<T> :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T :: [Decode]> List<T> :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): List<T> throws DecodeError
extend<T :: [Encode]> Deque<T> :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T :: [Decode]> Deque<T> :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): Deque<T> throws DecodeError
extend<T :: [Hashable, Encode], H :: [Hasher]> Set<T, H> :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T :: [Hashable, Decode]> Set<T, DefaultHasher> :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): Set<T, DefaultHasher> throws DecodeError
extend<K :: [Hashable, Encode], V :: [Encode], H :: [Hasher]> Map<K, V, H> :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<K :: [Hashable, Decode], V :: [Decode]> Map<K, V, DefaultHasher> :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): Map<K, V, DefaultHasher> throws DecodeError
extend<T0 :: [Encode], T1 :: [Encode]> (T0, T1) :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T0 :: [Decode], T1 :: [Decode]> (T0, T1) :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): (T0, T1) throws DecodeError
extend<T0 :: [Encode], T1 :: [Encode], T2 :: [Encode]> (T0, T1, T2) :: [Encode]

Conforms to Encode.

fn encode<E :: [Encoder]>(&e: E): void throws EncodeError
extend<T0 :: [Decode], T1 :: [Decode], T2 :: [Decode]> (T0, T1, T2) :: [Decode]

Conforms to Decode.

static fn decode<D :: [Decoder]>(&d: D): (T0, T1, T2) throws DecodeError