bitty/bytes
Byte-level parsers for reading, skipping, peeking, and matching raw
bytes. These parsers work at any bit position — when unaligned, bytes
are extracted bit-by-bit. When byte-aligned, zero-copy slicing is used.
After bit-level parsing with bitty/bits, call bits.align() before
resuming byte-aligned operations.
Values
pub fn byte() -> bitty.Parser(BitArray)
Parse a single byte and return it as a BitArray.
let assert Ok(b) = bitty.run(bytes.byte(), on: <<0xFF>>)
assert b == <<0xFF>>
pub fn byte_if(
predicate: fn(BitArray) -> Bool,
) -> bitty.Parser(BitArray)
Parse a single byte that satisfies the given predicate.
The predicate receives a 1-byte BitArray.
When byte-aligned, returns a zero-copy slice. When unaligned, the byte
is extracted individually.
let parser = bytes.byte_if(fn(b) { b == <<0xFF>> })
let assert Ok(value) = bitty.run(parser, on: <<0xFF>>)
assert value == <<0xFF>>
pub fn peek(bytes count: Int) -> bitty.Parser(BitArray)
Look ahead at the next count bytes without consuming them.
pub fn rest() -> bitty.Parser(BitArray)
Consume all remaining input as a BitArray.
Works at any bit position — the result may be non-byte-aligned.
pub fn skip(bytes count: Int) -> bitty.Parser(Nil)
Advance the parser position by count bytes, discarding the data.
pub fn tag(expected: BitArray) -> bitty.Parser(Nil)
Match an exact byte sequence at the current position and consume it. Fails if the bytes don’t match. Useful for magic numbers and fixed headers.
pub fn take(bytes count: Int) -> bitty.Parser(BitArray)
Parse exactly count bytes as a BitArray.
When byte-aligned, returns a zero-copy slice.
pub fn take_until(
predicate: fn(BitArray) -> Bool,
) -> bitty.Parser(BitArray)
Consume bytes until the predicate matches, returning everything before
the matching byte. Returns <<>> when zero bytes match.
When byte-aligned, returns a zero-copy slice. When unaligned, bytes are
extracted individually.
let parser = bytes.take_until(fn(b) { b == <<0x00>> })
let assert Ok(value) = bitty.run(parser, on: <<1, 2, 3, 0x00>>)
assert value == <<1, 2, 3>>
pub fn take_while(
predicate: fn(BitArray) -> Bool,
) -> bitty.Parser(BitArray)
Consume bytes while the predicate holds.
Returns <<>> when zero bytes match.
When byte-aligned, returns a zero-copy slice. When unaligned, bytes are
extracted individually.
let parser = bytes.take_while(fn(b) { b != <<0x00>> })
let assert Ok(value) = bitty.run(parser, on: <<1, 2, 3, 0x00>>)
assert value == <<1, 2, 3>>
pub fn take_while1(
predicate: fn(BitArray) -> Bool,
) -> bitty.Parser(BitArray)
Like take_while but requires at least one matching byte.
When byte-aligned, returns a zero-copy slice. When unaligned, bytes are
extracted individually.
let parser = bytes.take_while1(fn(b) { b != <<0x00>> })
let assert Ok(value) = bitty.run(parser, on: <<1, 2, 3, 0x00>>)
assert value == <<1, 2, 3>>