All notable changes to zaml are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.2.0 - 2026-10-09

Changed

  • Performance. Maps are now built with a single enif_make_map_from_arrays call per map instead of a per-pair enif_make_map_put, eliminating the O(n^2) rehashing on wide maps. String scalars are now returned as sub-binaries of the input (enif_make_sub_binary) rather than copied into freshly allocated binaries, so the parse no longer re-copies every string value. Together these take the 100k-key nested benchmark from ~0.65 s to ~0.53 s and shave the 1M-key flat benchmark to ~0.84 s, keeping the lead over fast_yaml at ~3.0–3.5×.

    The sub-binary path is guarded: we only sub-binary when the scalar pointer provably lies inside the input buffer, falling back to a copy otherwise, so the change stays correct across libyaml versions that may write quoted/block/folded scalars into their own buffer.

Fixed

  • Anchors and aliases. &name is now registered for scalars and for mapping/sequence starts, and *name resolves to the aliased term. Anchor names are copied into a parse-scoped arena because libyaml frees the event buffer after each event. Previously any document using an anchor returned :parse_error.

0.1.0 - 2026-09-05

Added

  • Elixir NIF: a Zig NIF wrapping libyaml for fast YAML 1.2 parsing in Elixir.
    • Zaml.load/1 parses a YAML binary and returns the corresponding Elixir term (maps, lists, integers, floats, booleans, :nil).
    • YAML 1.2 core schema scalar resolution for ints, floats, bools, and null.
    • Respects explicit !!str / !!int / !!float / !!bool / !!null tags.
    • Anchors and aliases (&name / *name).
    • Returns :error for non-binary input, :parse_error for malformed YAML, and :nil for an empty document.
  • NIF is compiled at mix compile via elixir_make and the project Makefile (also invokable as Mix task ZamlNif.Build).
  • mix zaml_nif.bench PATH Mix task for head-to-head benchmarking against fast_yaml.
  • Makefile driving the zig build-lib invocation directly, with pkg-config/Homebrew//usr libyaml auto-detection.
  • mix.exs auto-detects libyaml on common paths and exports CFLAGS/CPPFLAGS/LDFLAGS so rebar3-compiled deps (e.g. fast_yaml in the bench task) find it.
  • ExUnit test suite covering basic scalars, nested maps and lists, explicit tags, anchors, empty input, and parse-error handling.
  • Cross-language benchmark suite (benchmark/) comparing the NIF against fast_yaml, PyYAML, and ruamel.yaml.
  • benchmark/RESULTS.md with the measured numbers on a 1M-line flat mapping and a 100k-key nested mapping.

Notes

  • Merge keys (<<: *alias) are not yet expanded.
  • Multi-document input returns only the first document.