thrift_runtime_compact (thrift_runtime v0.7.0)
View SourceThrift compact protocol: value and message codecs as pure functions, wire-compatible with the Apache TCompactProtocol (the vendored 0.25.0 Erlang implementation is the golden reference).
The compact format differs from the binary protocol in four ways, all handled here:
- integers travel as ULEB128 varints, signed values zigzag-encoded (field ids too); the message seqid is a plain varint;
- doubles are little-endian;
- a struct field header packs the type into a nibble next to the field
id: ids within 1..15 of the previously written/read field id travel
as a delta in the high nibble, otherwise a zigzag varint id follows
the type byte. A boolean field has no payload — its nibble
(
16#01/16#02) IS the value; booleans as collection elements are one cbool byte (1/2); - collection sizes up to 14 fit the header byte's high nibble; a size of 15 in the nibble means a varint size follows.
Type descriptors, struct values, more-on-truncation semantics and the
error shapes match thrift_runtime_binary — the two codecs are
interchangeable behind thrift_runtime:protocol/0.
The uuid base type has no compact encoding (it postdates the format):
compiling a descriptor containing one succeeds, and encoding or decoding
through it fails with {type_not_supported, {base, uuid}, compact}.
Like the binary codec, descriptors are compiled before use — compact
type nibbles precomputed, struct fields indexed by id — with {ref, ...}
schemas cached in persistent_term and inline descriptors memoized per
process. See thrift_runtime_binary's moduledoc for the caching contract.
Ref descriptors also probe the generated module's compact_codec/1
first and dispatch to its specialized per-struct codecs, falling back
to the interpreter here when the export is missing.
Summary
Functions
Decodes a value of Type from the front of Binary.
Decodes TApplicationException from an EXCEPTION message payload.
Decodes a message envelope.
Encodes Value as Type, or fails with a tagged error.
Encodes TApplicationException as an EXCEPTION message payload.
Encodes a message envelope around Payload (already encoded as a
struct): protocol id, version-and-type byte, varint seqid, name string.
Skips one value of the given compact type nibble — the element nibble inside a collection header for lists, sets and maps.
Types
-type decode_result(Value) :: thrift_runtime_binary:decode_result(Value).
Functions
-spec decode(thrift_runtime_binary:type_desc(), binary()) -> decode_result(term()).
Decodes a value of Type from the front of Binary.
Returns {ok, Value, Rest}, more when Binary is a truncated valid
encoding, or a tagged error.
-spec decode_application_exception(binary()) -> decode_result(thrift_runtime_binary:application_exception()).
Decodes TApplicationException from an EXCEPTION message payload.
Unknown fields are skipped per the usual struct rules.
-spec decode_message(binary()) -> {ok, thrift_runtime_binary:message_type(), binary(), non_neg_integer(), binary()} | more | {error, term()}.
Decodes a message envelope.
Returns {ok, Type, Name, SeqId, Tail} where Tail is every byte
after the name (the struct payload plus anything that follows it),
more, or a tagged error. Only the current compact version (1) is
accepted — the format has no legacy variant.
-spec encode(thrift_runtime_binary:type_desc(), term()) -> {ok, iodata()} | {error, term()}.
Encodes Value as Type, or fails with a tagged error.
-spec encode_application_exception(binary(), non_neg_integer()) -> {ok, iodata()} | {error, term()}.
Encodes TApplicationException as an EXCEPTION message payload.
-spec encode_message(thrift_runtime_binary:message_type(), binary(), non_neg_integer(), iodata()) -> iodata().
Encodes a message envelope around Payload (already encoded as a
struct): protocol id, version-and-type byte, varint seqid, name string.
-spec skip_nibble(non_neg_integer(), binary()) -> {ok, binary()} | more | {error, term()}.
Skips one value of the given compact type nibble — the element nibble inside a collection header for lists, sets and maps.
Exported for the specialized codecs the generator emits: their decode loops skip unknown struct fields through this function, keeping skip-on-unknown-field semantics in one place.