Skip to content

# YAML

Glaze provides a YAML 1.2 reader and writer. The same compile-time reflection metadata used for JSON works for YAML, so you can reuse your `glz::meta` specializations without additional boilerplate.

> Note: YAML support requires a separate include. It is not included in `glaze/glaze.hpp`.

## Getting Started

Include `glaze/yaml.hpp` to access the YAML API:

    #include "glaze/yaml.hpp"

    struct retry_policy
    {
       int attempts = 5;
       int backoff_ms = 250;
    };

    template <>
    struct glz::meta<retry_policy>
    {
       using T = retry_policy;
       static constexpr auto value = object(&T::attempts, &T::backoff_ms);
    };

    struct app_config
    {
       std::string host = "127.0.0.1";
       int port = 8080;
       retry_policy retry{};
       std::vector<std::string> features{"metrics"};
    };

    template <>
    struct glz::meta<app_config>
    {
       using T = app_config;
       static constexpr auto value = object(&T::host, &T::port, &T::retry, &T::features);
    };

    app_config cfg{};
    std::string yaml{};
    auto write_error = glz::write_yaml(cfg, yaml);
    if (write_error) {
       const auto message = glz::format_error(write_error, yaml);
       // handle the error message
    }

    app_config loaded{};
    auto read_error = glz::read_yaml(loaded, yaml);
    if (read_error) {
       const auto message = glz::format_error(read_error, yaml);
       // handle the error message
    }

`glz::write_yaml` and `glz::read_yaml` return an `error_ctx`. The object becomes truthy when an error occurred; pass it to `glz::format_error` to obtain a human-readable explanation.

## YAML Output Example

The `app_config` structure above produces:

    host: "127.0.0.1"
    port: 8080
    retry:
      attempts: 5
      backoff_ms: 250
    features:
      - metrics

## YAML Input Example

Glaze supports both block style (with indentation) and flow style (compact) for reading:

Block style:

    host: localhost
    port: 9000
    retry:
      attempts: 6
      backoff_ms: 500
    features:
      - metrics
      - debug

Flow style:

    host: localhost
    port: 9000
    retry: {attempts: 6, backoff_ms: 500}
    features: [metrics, debug]

## Scalar Types

Glaze YAML supports the following scalar representations:

### Strings

    # Plain scalars (unquoted)
    name: hello world

    # Double-quoted with escape sequences
    message: "Hello\nWorld"

    # Single-quoted (literal, only '' escapes to ')
    path: 'C:\Users\name'

    # Literal block scalar (preserves newlines)
    description: |
      This is line 1.
      This is line 2.
      This is line 3.

    # Folded block scalar (folds newlines to spaces)
    summary: >
      This is a long
      paragraph that will
      be folded into one line.

Block scalar modifiers: - `|` (literal): Preserves all newlines exactly - `>` (folded): Converts newlines to spaces (paragraph style) - Chomping: `-` strips trailing newlines, `+` keeps all, default clips to one - Indentation indicator: `|2` or `>4` for explicit indent level

Double-quoted strings support YAML escape sequences including: - `\\`, `\"`, `\/`, `\n`, `\r`, `\t`, `\b`, `\f` - `\0` (null), `\a` (bell), `\v` (vertical tab), `\e` (escape) - `\xXX` (hex byte), `\uXXXX` (Unicode), `\UXXXXXXXX` (Unicode) - `\N` (next line U+0085), `\_` (non-breaking space U+00A0) - `\L` (line separator U+2028), `\P` (paragraph separator U+2029)

### Numbers

    integer: 42
    negative: -17
    float: 3.14
    scientific: 6.022e23
    hex: 0x1A
    octal: 0o755
    binary: 0b1010
    infinity: .inf
    neg_infinity: -.inf
    not_a_number: .nan

### Booleans

    enabled: true
    disabled: false

YAML 1.2 Core Schema is used, so `true`/`false` (case-insensitive) are recognized as booleans.

### Null

    value: null
    also_null: ~

## Collections

### Sequences (Arrays)

Block style:

    items:
      - first
      - second
      - third

Flow style:

    items: [first, second, third]

### Mappings (Objects)

Block style:

    person:
      name: John
      age: 30

Flow style:

    person: {name: John, age: 30}

## Document Markers

Glaze supports YAML document markers:

    ---
    # Document start marker (optional)
    key: value
    ...
    # Document end marker (optional)

The `---` marker indicates the start of a document and is skipped during parsing. The `...` marker indicates the end of a document; any content after it is ignored.

## File Helpers

Glaze provides file-oriented helpers:

    std::string buffer{};
    glz::write_file_yaml(cfg, "config.yaml"); // writes to disk

    app_config loaded{};
    glz::read_file_yaml(loaded, "config.yaml");

## Using the Generic API

You can use the generic `glz::read`/`glz::write` with YAML by setting the format option:

    app_config cfg{};
    auto ec = glz::read<glz::opts{.format = glz::YAML}>(cfg, yaml_text);
    if (ec) {
       const auto message = glz::format_error(ec, yaml_text);
       // handle error
    }

    std::string yaml{};
    auto ec = glz::write<glz::opts{.format = glz::YAML}>(cfg, yaml);

## YAML Options

The `glz::yaml::yaml_opts` struct provides YAML-specific options:

Option | Default | Description
--- | --- | ---
`error_on_unknown_keys` | `true` | Error on unknown YAML keys
`skip_null_members` | `true` | Skip null values when writing
`indent_width` | `2` | Spaces per indent level
`flow_style` | `false` | Use flow style (compact) output

Example with flow style output:

    auto ec = glz::write<glz::yaml::yaml_opts{.flow_style = true}>(cfg, yaml);
    // Output: {host: "127.0.0.1", port: 8080, retry: {attempts: 5, backoff_ms: 250}, features: [metrics]}

## Supported Types

YAML support leverages the same type system as JSON. All types that work with `glz::read_json`/`glz::write_json` also work with YAML:

- Arithmetic types (integers, floating-point)
- `std::string`, `std::string_view`
- `std::vector`, `std::array`, `std::deque`, `std::list`
- `std::map`, `std::unordered_map`
- `std::optional`, `std::unique_ptr`, `std::shared_ptr`
- `std::variant`
- `std::tuple`
- User-defined types with `glz::meta` or pure reflection
- Enums (as integers or strings with `glz::meta`)

## Tag Validation

Glaze supports YAML Core Schema tags and validates them against the C++ types being parsed. This catches type mismatches at parse time.

### Supported Tags

Tag | Verbatim Form | Valid C++ Types
--- | --- | ---
`!!str` | `!<tag:yaml.org,2002:str>` | `std::string`, `std::string_view`
`!!int` | `!<tag:yaml.org,2002:int>` | `int`, `int64_t`, `uint32_t`, etc.
`!!float` | `!<tag:yaml.org,2002:float>` | `float`, `double`
`!!bool` | `!<tag:yaml.org,2002:bool>` | `bool`
`!!null` | `!<tag:yaml.org,2002:null>` | `std::optional`, `std::unique_ptr`, pointers
`!!seq` | `!<tag:yaml.org,2002:seq>` | `std::vector`, `std::array`, etc.
`!!map` | `!<tag:yaml.org,2002:map>` | `std::map`, structs, objects

### Examples

    # Valid: tag matches C++ type
    name: !!str "Alice"
    count: !!int 42
    rate: !!float 3.14
    enabled: !!bool true
    items: !!seq [1, 2, 3]
    config: !!map {key: value}

    // When parsing into int, !!str tag causes an error
    std::string yaml = "!!str 42";
    int value{};
    auto ec = glz::read_yaml(value, yaml);
    // ec.ec == glz::error_code::syntax_error (tag mismatch!)

### Tag Compatibility

- `!!int` is valid for floating-point types (widening conversion allowed)
- `!!float` is NOT valid for integer types
- Unknown or custom tags (e.g., `!mytag`, `!!custom`) produce `feature_not_supported` error

## Limitations

The current YAML implementation has some limitations compared to the full YAML 1.2 specification:

### Not Supported

- Anchors and aliases (`&anchor`, `*alias`) - These will produce a `feature_not_supported` error
- Custom tags (`!mytag`) - Only YAML Core Schema tags are supported
- Multi-document streams - Only single documents are supported
- Complex keys - Only simple scalar keys are supported

### Tab Indentation

YAML forbids tab characters for indentation. Using tabs will produce a `syntax_error`:

    # This will error:
    key:
        value  # Tab character - not allowed!

Always use spaces for indentation in YAML.