hanki

codec

stdlib/core/codec.hk: pure-callable serialization entry points.

to_bytes / from_bytes are the @encapsulated boundary over the action-based Encode/Decode framework (§ core encode/decode). Each owns a local BytesBuilder or BytesReader sink, and although it drives the mutating (empty-effect-row) encode! / decode! workhorse internally, it is itself externally pure: no !, callable from comptime, where-invariants, and content-hashing (HANKI.md §6, @encapsulated). The codec is unchanged: the encapsulation boundary sits here, at the sink-owning entry points, and there is no value-threading rewrite and no per-byte encode penalty.

Comptime-foldable each way: every intrinsic the encode and decode paths reach, the builder and reader ops, the wire-reinterprets, the fixed-width bitwise family and the width conversions, is in the meta VM's fold set, and a binary constant can therefore be built and read back at compile time.

to_bytes

def to_bytes<T: Encode>(v: T) -> bytes

Serialize v to the built-in binary format. Pure: the BytesBuilder sink is allocated and finalized inside this function, and nothing mutable escapes.

to_bytes(7i32).length => 4

from_bytes

def from_bytes<T: Decode>(input: bytes) -> Result<T, DecodeError>

Deserialize a T from the built-in binary format. Pure for the same reason; malformed input is a DecodeError value (in the Result), never a throw.

from_bytes(to_bytes(7i32)).unwrap_or(0i32) => 7i32

FOLDWIRE

_FOLD_WIRE: bytes = to_bytes(7i32)

Top-level bindings are compile-time-evaluated, and these two are the probe: this module does not compile at all unless a codec round-trip folds (HANKI.md section 16) - the comptime-constant capability the @encapsulated conversion promised, pinned here so a fold-set regression fails the build in place of a downstream meta const.

FOLDBACK

_FOLD_BACK: i32 = from_bytes(_FOLD_WIRE).unwrap_or(0i32)

encoded_len

def encoded_len<T: Encode>(v: T) -> int

The byte length of v's binary encoding. A pure def, with no !: it type-checks only because to_bytes is externally pure, the @encapsulated payoff (a pure function may call it).

encoded_len(7i32) => 4