yam.cr

Crystal bindings for YAM, a spinich-powered YAML parser and emitter

yam.cr

Crystal bindings for yam, a fast YAML 1.2 parser written in C11. SIMD-accelerated, zero-copy, arena-allocated.

Installation

Add the dependency to your shard.yml:

dependencies:
  yam:
    github: trans/yam.cr

Then run shards install. The C library is built automatically via the postinstall script.

Requires a C11 compiler (GCC or Clang).

Quick Start

require "yam"

data = Yam.parse("name: yam\nversion: 0.1.0")
data["name"].as_s   # => "yam"
data["version"].as_s # => "0.1.0"

Usage

Parsing to Any

Yam.parse returns a Yam::Any with automatic scalar resolution (YAML 1.2 Core schema: null, bool, int, float):

data = Yam.parse <<-YAML
  server:
    host: localhost
    port: 8080
    debug: true
  YAML

data["server"]["host"].as_s    # => "localhost"
data["server"]["port"].as_i    # => 8080
data["server"]["debug"].as_bool # => true

Quoted scalars are always strings:

Yam.parse(%("42")).as_s # => "42"
Yam.parse("42").as_i    # => 42

Multi-document

docs = Yam.parse_all("---\nfoo\n---\nbar")
docs.size        # => 2
docs[0].as_s     # => "foo"
docs[1].as_s     # => "bar"

Navigating data

data = Yam.parse("a:\n  b:\n    c: deep")

data["a"]["b"]["c"].as_s   # => "deep"
data.dig("a", "b", "c").as_s # => "deep"
data.dig?("a", "x")          # => nil

data["a"].size # => 1

Anchors and aliases

yaml = <<-YAML
  defaults: &defaults
    adapter: postgres
    host: localhost
  production:
    <<: *defaults
    database: mydb
  YAML

data = Yam.parse(yaml)
data["production"]["host"].as_s     # => "localhost"
data["production"]["database"].as_s # => "mydb"

AST (Nodes API)

For full control over the parsed structure, use the Nodes API:

doc = Yam::Nodes.parse("key: value")
map = doc[0].as(Yam::Nodes::Mapping)

key = map.nodes[0].as(Yam::Nodes::Scalar)
key.value        # => "key"
key.start_line   # => 1
key.start_column # => 1

val = map.nodes[1].as(Yam::Nodes::Scalar)
val.value        # => "value"
val.start_line   # => 1
val.start_column # => 6

Node types: Scalar, Sequence, Mapping, Alias.

PullParser (low-level)

Event-based streaming parser for maximum control:

Yam::PullParser.new("name: yam\nversion: 0.1.0") do |parser|
  parser.read_stream do
    parser.read_document do
      parser.read_mapping do
        key = parser.read_scalar   # => "name"
        value = parser.read_scalar # => "yam"
        # ...
      end
    end
  end
end

API

Yam

Method Returns Description
Yam.parse(data) Yam::Any Parse a single YAML document
Yam.parse_all(data) Array(Yam::Any) Parse all documents in a stream

Yam::Any

Method Description
as_s, as_s? Access as String
as_i, as_i? Access as Int32
as_i64, as_i64? Access as Int64
as_f, as_f? Access as Float64
as_bool, as_bool? Access as Bool
as_a, as_a? Access as Array(Yam::Any)
as_h, as_h? Access as Hash(Yam::Any, Yam::Any)
as_bytes, as_bytes? Access as Bytes
as_time, as_time? Access as Time
[index], [key] Index by Int or String
[]? Non-raising index access
dig(keys...) Traverse nested structures
dig?(keys...) Non-raising dig
size Collection size
raw Underlying Type union value

Yam::Nodes

Type Description
Scalar Scalar value (value, style, anchor, tag)
Sequence Ordered list (style, nodes)
Mapping Key-value pairs (style, nodes as flat key/val/key/val)
Alias Alias reference (value, resolved)
Document Document container (nodes)

All nodes carry start_line, start_column, end_line, end_column (1-based source positions).

License

MIT

Repository

yam.cr

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 0
  • about 10 hours ago
  • February 9, 2026
License

MIT License

Links
Synced at

Mon, 09 Feb 2026 14:24:34 GMT

Languages