9.3 Wire-формат OxL
Бинарный формат OxL — кодирование protobuf 3 со следующими отображениями:
| OxL | protobuf |
|---|---|
data | message |
enum без полей | enum (значение 0 зарезервировано под «неизвестно») |
enum с полями, объединение A | B | oneof, по полю-сообщению на вариант или тип |
T? | поле optional; none — отсутствие поля |
i8 i16 i32, u8 u16 u32 | int32 / uint32 (sint32 при @zigzag) |
i64, u64 | int64 / uint64 |
i128, u128 | bytes (16 байт, little-endian) |
f32, f64 | float / double |
char | uint32 |
str | string |
bytes | bytes |
List<T>, [T; N] | repeated (packed для чисел) |
Map<K, V> | map (K — целые, str, bool); иначе repeated пар |
Set<T> | repeated |
| кортеж | message с полями 1..n |
distinct T, уточнённый T | как T |
Duration, Time | google.protobuf.Duration, google.protobuf.Timestamp |
Date, LocalDateTime, ZonedTime | message oxl.Date, oxl.LocalDateTime, oxl.ZonedTime |
ActorRef<A> | message oxl.ActorRef |
secret<T> | как T; допускается только в бинарном формате поверх TLS и в журнале с шифрованием; JSON-кодировщик отвергает такие поля (ошибка компиляции при статически известном формате, иначе EncodeError) |
JSON — каноническое JSON-отображение protobuf.
MessagePack и CBOR (formats.msgpack, formats.cbor; D-8053; DIV-006; D-7600, D-7601) — самоописывающие форматы; они кодируют значение по схеме типа так:
| OxL | MessagePack / CBOR |
|---|---|
data | map; ключи — имена полей (текст); поле none не пишется, nil при чтении принимается как none |
| целые до 64 бит | родное целое в кратчайшей форме (неотрицательное знаковое пишется как беззнаковое; CBOR major 0/1) |
i128, u128 | 16 байт little-endian (bin / byte string) |
f32, f64 | float одинарной / двойной точности (декодер CBOR читает и половинную; целое принимается как число с плавающей точкой) |
str, bytes | str (text string, UTF-8 проверяется) / bin (byte string) |
List<T>, Set<T>, [T; N], кортеж | array |
Map<K, V> | map с ключами любого сериализуемого типа (при повторе ключа побеждает последний) |
enum без полей | имя варианта (неизвестное значение @open enum — его номер) |
enum с полями, объединение нескольких типов | map из одной записи {Вариант: {поля}} |
T? | значение или nil |
() | пустой map |
Duration, LocalDateTime | целое число наносекунд; Date — целое число дней |
Time | MessagePack: расширение timestamp (тип −1; 32-, 64- или 96-битная форма, кратчайшая из подходящих); CBOR: тег 0 с текстом RFC 3339 (декодер принимает и тег 1) |
ActorRef<A> | текст адреса, как в JSON |
distinct, уточнённый, @repr, view | как в других форматах; проверки выполняются при декодировании |
Декодеры принимают то, что пишут другие реализации: любую ширину целых, CBOR с неопределённой длиной, bignum (тег 2/3), помещающиеся в 64 бита, прочие теги (прозрачно), undefined как nil, неизвестные ключи (пропускаются). Они отвергают: обрыв документа, лишние байты после значения, зарезервированные байты, неверный UTF-8, целое вне диапазона типа (Invalid), вложенность глубже 128, заявленную длину больше остатка входа. @codec(…) выбирается по форматам oxl и json; MessagePack и CBOR используют представление поля по умолчанию. secret<T> в этих форматах отвергается (EncodeError.Secret), как и в JSON.
Связанные диагностики
См. также
Исходник: docs/spec/oxl-standard.md