bitty
A zero-copy binary parser combinator library for Gleam.
Installation
gleam add bitty
Quick Example
Parsing a simple TLV (tag-length-value) structure
Using Gleam’s use syntax for monadic bind:
import bitty as p
import bitty/bytes as b
import bitty/num
pub type Tlv {
Tlv(tag: Int, length: Int, value: BitArray)
}
pub fn tlv() -> p.Parser(Tlv) {
use tag <- p.then(num.u8())
use len <- p.then(num.u8())
use value <- p.then(b.take(len))
p.success(Tlv(tag, len, value))
}
valueis a zero-copy slice.- No hidden allocation.
- Fully portable.
Core Concepts
Parser
pub opaque type Parser(a)
Parsers operate over BitArray and track:
- Byte offset
- Bit offset
- Commit state for backtracking control
Running a parser
pub fn run(parser: Parser(a), on input: BitArray)
-> Result(a, BittyError)
pub fn run_partial(parser: Parser(a), on input: BitArray)
-> Result(#(a, BitArray), BittyError)
runrequires full consumption.run_partialreturns the zero-copy remainder.
Length-Bounded Parsing
Critical for TLV-style formats:
pub fn within_bytes(byte_len: Int, run inner: Parser(a))
-> Parser(a)
Parse exactly byte_len bytes as a sub-stream.
Used for:
- ASN.1 SEQUENCE
- PNG chunks
- Length-prefixed frames
- Nested protocols
Numeric Decoding
import bitty/num
num.u8()
num.u16(num.BigEndian)
num.u32(num.LittleEndian)
num.u64(num.BigEndian)
All integer parsers return Int. On the JavaScript target, 64-bit values
above 2^53 - 1 (9,007,199,254,740,991) may lose precision due to IEEE 754
double-precision floating-point limitations.
Bit-Level Parsing
import bitty/bits
use flag <- p.then(bits.bit())
use value <- p.then(bits.uint(5))
use _ <- p.then(p.align())
p.success(#(flag, value))
Byte-aligned parsing is the fast path. Bit parsing is explicit and opt-in.
Error Reporting
Structured error type:
pub type BittyError {
BittyError(
at: Location,
expected: List(String),
context: List(String),
message: Option(String),
)
}
Add readable labels:
p.label(parser, named: "ASN.1 length")
p.context(parser, in: "TLS handshake")
You get precise error locations and meaningful context stacks.