Filo.Value (Filo v0.2.0)

Copy Markdown View Source

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 padding

decode/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

native()

@type native() :: nil | integer() | float() | binary() | {:blob, binary()}

t()

@type t() :: %{required(String.t()) => term()}

Functions

decode(map)

@spec decode(t()) :: native()

Decodes a Hrana value map into a native Elixir term.

encode(v)

@spec encode(native()) :: t()

Encodes a native Elixir term into a Hrana value map.

encode_json(v)

@spec encode_json(native()) :: iodata()

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.