Skip to content

yaml

stable

Parse, generate, and manipulate YAML data. Supports multi-document streams, dot-path access, deep merging, and file I/O.

use plugin yaml::{parse, stringify, parse_file, …}
10 functions Data Formats
/ filter jk navigate Esc clear
Functions (10)
  1. parse Parse a YAML string into a table
  2. stringify Serialize a table to a YAML string
  3. parse_file Read and parse a YAML file
  4. write_file Serialize a table and write to file
  5. parse_multi Parse a multi-document YAML string
  6. get_value Read a value by dot-separated path
  7. set_value Set a value at a dot-separated path
  8. merge Deep-merge two tables
  9. validate Check whether a YAML string is valid
  10. keys Return the top-level keys of a table

Overview

yaml is a self-contained toolkit for reading, writing, and reshaping YAML data as ordinary Zolo tables. There are no handles or opaque document objects: parsing a YAML string hands you a plain table you can index and iterate, and serializing takes any table straight back to text. YAML mappings become string-keyed tables, sequences become 1-indexed integer-keyed tables, and that round-trip is the whole mental model.

Use it whenever you load configuration from disk, transform structured data, or emit YAML for another tool to consume. Beyond raw parse/stringify, the plugin adds ergonomic helpers for the things configuration code actually does: reach into nested values by dot path (get_value), patch them immutably (set_value), layer defaults under overrides (merge), validate untrusted input (validate), and stream multi-document files (parse_multi). All transformations return new tables — nothing mutates in place.

Common patterns

Load a config file, read a nested value, patch it, and write it back:

use plugin yaml::{parse_file, get_value, set_value, write_file}

let cfg = parse_file("config/app.yaml")
print("current host: {get_value(cfg, "server.host")}")

let updated = set_value(cfg, "server.host", "0.0.0.0")
write_file("config/app.yaml", updated)

Layer environment overrides on top of defaults before using the result:

use plugin yaml::{parse, merge, get_value}

let defaults = parse("log_level: info\ntimeout: 30\nretries: 3\n")
let overrides = parse("log_level: debug\nretries: 5\n")
let cfg = merge(defaults, overrides)

print("level: {get_value(cfg, "log_level")}")
print("timeout: {get_value(cfg, "timeout")}")

Validate untrusted YAML before parsing it:

use plugin yaml::{validate, parse}

let text = "name: alice\nrole: admin\n"
let check = validate(text)
if check["valid"] {
  let data = parse(text)
  print("loaded {data["name"]}")
} else {
  print("rejected: {check["error"]}")
}

Parse a YAML string into a table

Parses a YAML-formatted string and returns the result as a Zolo table. YAML mappings become string-keyed tables; sequences become integer-keyed tables.

use plugin yaml::{parse}

let config = parse("host: localhost\nport: 5432\n")
print(config["host"])
print(config["port"])

Nested mappings and sequences come back as nested tables — sequences are 1-indexed:

use plugin yaml::{parse}

let data = parse("servers:\n  - web1\n  - web2\nport: 8080\n")
print(data["servers"][1])
print(data["servers"][2])
print(data["port"])

Serialize a table to a YAML string

Serializes a Zolo table (or any value) into a YAML string. Integer-keyed tables are emitted as YAML sequences; string-keyed tables become YAML mappings.

use plugin yaml::{stringify}

let data = #{"name": "alice", "roles": ["admin", "user"]}
let text = stringify(data)
print(text)

stringify is the inverse of parse, so the two round-trip cleanly — handy for normalizing or pretty-printing config:

use plugin yaml::{parse, stringify}

let messy = parse("port: 8080\nhost: localhost\n")
print(stringify(messy))

Read and parse a YAML file

Reads the file at path from disk and parses its YAML content. Useful for loading configuration files at runtime.

use plugin yaml::{parse_file}

let cfg = parse_file("config/app.yaml")
print(cfg["database"]["host"])

Serialize a table and write to file

Serializes table to YAML and writes the result to the file at path, creating or overwriting it.

use plugin yaml::{write_file}

let settings = #{"debug": true, "max_connections": 10}
write_file("config/settings.yaml", settings)

Parse a multi-document YAML string

Parses a YAML string that contains multiple documents separated by ---. Returns a table where each entry is one parsed document (1-indexed).

use plugin yaml::{parse_multi}

let docs = parse_multi("name: alice\n---\nname: bob\n")
print(docs[1]["name"])
print(docs[2]["name"])

Read a value by dot-separated path

Retrieves a nested value from table using a dot-separated key path such as "server.host". Returns nil if any segment along the path is missing.

use plugin yaml::{parse, get_value}

let cfg = parse("server:\n  host: localhost\n  port: 8080\n")
let host = get_value(cfg, "server.host")
let port = get_value(cfg, "server.port")
print("{host}:{port}")

A path that reaches a missing key returns nil, so you can supply a fallback without inspecting the structure first:

use plugin yaml::{parse, get_value}

let cfg = parse("server:\n  host: localhost\n")
let timeout = get_value(cfg, "server.timeout")
if timeout == nil {
  print("no timeout configured")
}

Set a value at a dot-separated path

Returns a new table with the value at the dot-separated path set to value. Intermediate keys are created automatically if they do not exist. The original table is not mutated.

use plugin yaml::{parse, set_value, stringify}

let cfg = parse("server:\n  host: localhost\n")
let updated = set_value(cfg, "server.host", "0.0.0.0")
let updated2 = set_value(updated, "server.port", 9000)
print(stringify(updated2))

Deep-merge two tables

Deep-merges overlay into base. For mapping tables, keys from overlay overwrite matching keys in base and new keys are added. For arrays, the overlay replaces the base array entirely.

use plugin yaml::{parse, merge, stringify}

let defaults = parse("log_level: info\ntimeout: 30\n")
let overrides = parse("log_level: debug\nmax_retries: 5\n")
let final_cfg = merge(defaults, overrides)
print(stringify(final_cfg))

The merge is recursive, so nested mappings are combined key-by-key rather than replaced wholesale:

use plugin yaml::{parse, merge, get_value}

let base = parse("server:\n  host: localhost\n  port: 80\n")
let over = parse("server:\n  port: 443\n")
let cfg = merge(base, over)
print(get_value(cfg, "server.host"))
print(get_value(cfg, "server.port"))

Check whether a YAML string is valid

Checks whether data is a valid YAML string without fully parsing it. Returns a table with a valid boolean field. On failure, also includes an error string describing the problem.

use plugin yaml::{validate}

let result = validate("key: value\n  bad_indent: oops")
if result["valid"] {
  print("YAML is valid")
} else {
  print("Error: {result["error"]}")
}

Return the top-level keys of a table

Returns a 1-indexed array of the top-level keys of table. Keys are returned as strings or integers, preserving their original type.

use plugin yaml::{parse, keys}

let cfg = parse("host: localhost\nport: 5432\ndebug: false\n")
let k = keys(cfg)
print(k[1])
print(k[2])
print(k[3])

Pair it with get_value to walk every top-level entry of a parsed document:

use plugin yaml::{parse, keys, get_value}

let cfg = parse("host: localhost\nport: 5432\n")
for key in keys(cfg) {
  print("{key} = {get_value(cfg, key)}")
}
enespt-br