Hrana value codec.
Hrana represents SQLite values as tagged JSON maps:
%{"type" => "null"}
%{"type" => "integer", "value" => "42"} # i64 carried as a string, for precision
%{"type" => "float", "value" => 3.14}
%{"type" => "text", "value" => "..."}
%{"type" => "blob", "base64" => "..."} # standard base64, no paddingdecode/1 turns a Hrana value into a native Elixir term suitable for binding
into SQLite; encode/1 turns a native term back into a Hrana value. A text
value decodes to a binary and a blob to {:blob, binary}, so the two stay
distinguishable when re-encoding.
Summary
Functions
Decodes a Hrana value map into a native Elixir term.
Encodes a native Elixir term into a Hrana value map.
Encodes a native term straight to Hrana-value JSON iodata — the JSON transports' fast path.
Types
Functions
Decodes a Hrana value map into a native Elixir term.
Encodes a native Elixir term into a Hrana value map.
Encodes a native term straight to Hrana-value JSON iodata — the JSON transports' fast path.
encode/1's tagged map exists only to be consumed by a JSON encoder on those
transports, costing a map + key/tag binaries per cell and a second full traversal by
Jason; row encoding is the dominant per-request CPU of a SQL proxy, and the
intermediate layer roughly doubled it. This emits the final wire bytes directly —
five value shapes, all trivially concatenable. Floats and text delegate to
Jason.encode_to_iodata!/1 so number formatting and string escaping stay
byte-identical to the map path (pinned by test); an invalid-UTF-8 binary falls back
to blob exactly as encode/1 does, via the encoder's own rejection — which also
drops the String.valid?/1 pre-scan (the map path walks every text cell twice:
validity here, escaping in Jason).
The protobuf transports keep consuming encode/1's maps — this is JSON-only.