thrift_runtime_compact (thrift_runtime v0.7.0)

View Source

Thrift 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

decode_result(Value)

-type decode_result(Value) :: thrift_runtime_binary:decode_result(Value).

Functions

decode/2

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.

decode_application_exception(Bin)

-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.

decode_message/1

-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.

encode/2

-spec encode(thrift_runtime_binary:type_desc(), term()) -> {ok, iodata()} | {error, term()}.

Encodes Value as Type, or fails with a tagged error.

encode_application_exception(Message, Code)

-spec encode_application_exception(binary(), non_neg_integer()) -> {ok, iodata()} | {error, term()}.

Encodes TApplicationException as an EXCEPTION message payload.

encode_message(Type, Name, SeqId, 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.

skip_nibble/2

-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.