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:
YAML Input Example¶
Glaze supports both block style (with indentation) and flow style (compact) for reading:
Block style:
Flow style:
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¶
YAML 1.2 Core Schema is used, so true/false (case-insensitive) are recognized as booleans.
Null¶
Collections¶
Sequences (Arrays)¶
Block style:
Flow style:
Mappings (Objects)¶
Block style:
Flow style:
Document Markers¶
Glaze supports YAML document markers:
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
}
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_viewstd::vector,std::array,std::deque,std::liststd::map,std::unordered_mapstd::optional,std::unique_ptr,std::shared_ptrstd::variantstd::tuple- User-defined types with
glz::metaor 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¶
!!intis valid for floating-point types (widening conversion allowed)!!floatis NOT valid for integer types- Unknown or custom tags (e.g.,
!mytag,!!custom) producefeature_not_supportederror
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 afeature_not_supportederror - 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:
Always use spaces for indentation in YAML.