Thrifty - a Gleamourous Apache Thrift Compact Protocol Library.
Thrifty is a pure Gleam implementation of the Apache Thrift Compact Protocol. It targets predictable behaviour, strict boolean semantics, and interoperability with golden payloads produced by official Thrift stacks.
| Use case | What Thrifty provides |
|---|---|
| Runtime decoding | Immutable reader with configurable limits, compatibility with legacy booleans, schema-agnostic skip support |
| Encoding | Writer helpers for primitives, containers, and struct headers |
| Testing harness | Deterministic fuzzing CLI, property tests, and golden vector validation |
Features
- Compact Protocol reader/writer covering integers, doubles, strings/binaries, and containers
- ZigZag and VarInt helpers with boundary checks and clear error reporting
- Field header decoding (short and long delta) with inline boolean handling
- Strict boolean policy (
AcceptCanonicalOnly) enforced across container element reads and skips - Reader options for depth, container size, and string length limits to guard untrusted payloads
- Deterministic fuzz harness with optional persistence of failing mutations under
artifact/fuzz-failures/ - Extensive test suite: golden vectors, structural property tests, and targeted regression cases
Getting Started
Prerequisites
- Gleam ≥ 1.13.0
- Erlang/OTP ≥ 28 (tested with 28.1)
- rebar3 ≥ 3.25.1 (for Hex packaging and publishing)
Installation (Hex)
Add Thrifty as a dependency once published:
// gleam.toml
[dependencies]
thrifty = "~> 1.0"
Local Development
gleam deps download
gleam test # run unit, property, and golden tests
gleam run -m thrifty # execute example entrypoint (if configured)
Golden payloads live under artifact/golden/; tests read directly from this directory. If you regenerate payloads out of band, keep filenames stable so golden tests discover them automatically.
Explore hands-on guides under docs/examples/ for decoding, encoding, skipping unknown fields, strict-boolean enforcement, and fuzz harness walkthroughs.
Project Layout
artifact/
golden/ # canonical Compact Protocol payloads used in tests
fuzz-failures/ # failing fuzz cases (enabled on demand)
src/ # library implementation modules
test/ # gleeunit test suites (unit, property, golden)
.github/workflows/ # GitHub Actions CI pipelines
Key Modules
thrifty/reader.gleam: public reader API (read_struct,skip_value, primitives)thrifty/writer.gleam: writer helpers for Compact Protocol encodingthrifty/field.gleam,thrifty/container.gleam: header and container decoding logicthrifty/fuzz_cli.gleam: deterministic fuzz harness with optional persistencethrifty/fuzz_persistence.gleam: helper used by the harness to persist failing inputs
Fuzz Harness & Failure Persistence
The fuzz CLI mutates golden payloads deterministically. Set the internal toggle or expose a CLI flag to enable persistence:
const save_failures_enabled = True
const save_failures_dir = "artifact/fuzz-failures"
When enabled, failing payloads and slim metadata (seed, iteration, reason) are written to the target directory for later triage. Tests under test/thrifty/fuzz_persistence_test.gleam exercise this pipeline.
For long-running fuzz jobs in CI, upload artifact/fuzz-failures/ as a build artifact so failures can be replayed locally.
Testing & Tooling
gleam testcovers all suites and currently exercises 79 assertions.- GitHub Actions workflows:
run-tests.yml: primary CI (gleam test).validate-goldens.yml: ensures golden vectors are up to date.fuzz-long.yml: optional longer fuzz runs.publish-on-ci-main.yml: gated Hex publish upon release once secrets are configured.
- Packaging checks:
rebar3 hex buildverifies Hex metadata and produces the.tarartifact under_build/default/lib/thrifty/hex/.
Regenerating Golden Payloads
Golden payloads are sourced from reference implementations (e.g., thriftpy2 or Apache Thrift Java). A typical workflow is:
- Produce binaries with the upstream tool of choice (store generator scripts alongside other tooling if you add them).
- Copy the resulting Compact payloads into
artifact/golden/. - Extend
test/thrifty/golden_test.gleamor other suites to assert the expected decoding behaviour. - Run
gleam testto validate compatibility.
License
Licensed under the Apache License, Version 2.0.