serializing values

Outputting TOML Files #

Using toml::format, you can convert a toml::value to a string.

#include <toml.hpp>
#include <cassert>

int main()
{
    const toml::value v(toml::table{
        {"a", 42},
        {"b", "foo"},
    });
    const std::string s = toml::format(v);

    const toml::value u = toml::parse_str(s);

    assert(u.at("a").as_integer() == 42);
    assert(u.at("b").as_string()  == "foo");

    return 0;
}

If the toml::value contains a table_type, it is interpreted as the root table of the file.

If a toml::value containing anything other than table_type is passed, only that value is formatted.

Certain format specifications may require a key to be provided for formatting. For example, toml::array_format::array_of_tables formats as [[array.of.tables]], which requires key access.

If a format specification that requires a key is provided without a key, a toml::serialization_error is thrown.

Additionally, if there are values that contradict the format specification, a toml::serialization_error is thrown. For instance, specifying integer_format::hex for a negative integer, or string_format::literal for a string containing newlines, will cause an error.

The method for specifying formats is explained later.

Outputting with Keys #

You can pass a key to toml::format as a std::string.

In this case, the key is considered to be under the root table, and the passed value corresponds to that key.

For nested keys, you can pass a std::vector<std::string>.

#include <toml.hpp>
#include <cassert>

int main()
{
    const toml::value v(toml::table{
        {"a", 42},
        {"b", "foo"},
    });
    const std::string s = toml::format("bar", v);

    const toml::value u = toml::parse_str(s);

    assert(u.at("bar").at("a").as_integer() == 42);
    assert(u.at("bar").at("b").as_string()  == "foo");

    return 0;
}

Specifying Formats #

Each type in toml::value has a corresponding format information type.

For toml::value::integer_type, there is toml::integer_format_info. For toml::value::table_type, there is toml::table_format_info.

These format information types are set when parsing and are retained even if the value is changed, as long as the type remains the same.

You can access and directly edit these formats using member functions like as_integer_fmt() or as_table_fmt().

Below are some examples explaining how to use these formats.

For more details on how to access formats, refer to the toml::value reference. For a complete list and detailed information on format information classes, see the format reference.

Specifying Integer Formats #

For integers, you can specify the radix, width, and the position of _.

When using hex, oct, or bin, values are padded with zeros until the specified width is reached. For dec, the width specification adds spaces, which are not parsed.

For more details, see the integer format reference.

Single-Line and Multi-Line Arrays #

For arrays, you can specify toml::array_format::oneline or toml::array_format::multiline.

# oneline
a = [1, 2, 3, 4, 5]
# multiline
a = [
  1,
  2,
  3,
  4, 
  5
]

When using multiline, you can specify the indentation. Each element is indented by the amount specified in body_indent, and the closing bracket ] is indented by the amount specified in closing_indent.

The type of character used for indentation is specified by indent_type, and you can choose between toml::indent_char::space or toml::indent_char::tab.

Ensure that the same type of character is used for indentation throughout the document.

If different types of characters are specified for indentation within the same file, the result is undefined. Some form of indentation will be applied, but the type of character and the depth of the indentation may be inconsistent.

If all elements of an array have table_type, you can specify toml::array_format::array_of_tables.

If you do not specify array_of_tables and use multiline, the tables will be formatted as inline tables.

# multiline
a = [
  {foo = 42},
  {bar = "hoge"},
]

# array_of_tables
[[a]]
foo = 42

[[a]]
bar = "hoge"

By default, toml::array_format::default_format is used. This automatically selects an appropriate format.

For example, with default_format, if all elements are table_type, it will choose array_of_tables. Short arrays are formatted as oneline, while long or nested arrays, or those with complex elements, are formatted as multiline.

For more details, see the array format reference.

Inline Tables #

To format a table as an inline table, specify toml::table_format::oneline. For standard tables, use toml::table_format::multiline.

oneline = {a = 42, b = "foo"}

[multiline]
a = 42
b = "foo"

In TOML v1.1.0, line breaks within inline tables are allowed. In this case, use toml::table_format::multiline_oneline. This is only applied if the corresponding feature flag is set to true as per the TOML version specification described later.

multiline_oneline = {
    a = 42,
    b = "foo"
}

For more details, see the table format reference.

Specifying the TOML Language Version for Output #

Certain language features, such as line breaks within inline tables and \x escape sequences, are only available after TOML v1.1.0.

The toml::format function accepts a toml::spec as its argument.

This allows you to specify the version of TOML to use during serialization.

When you use toml::parse with a toml::spec to leverage new features, the parsed values may contain format information that is only compatible with that specific version. Ensure that you pass the same toml::spec to toml::format to maintain compatibility.

#include <toml.hpp>
#include <iostream>

int main()
{
    const auto spec = toml::spec::v(1, 1, 0);

    const toml::value v = toml::parse("input.toml", spec);

    std::cout << toml::format(v, spec) << std::endl;

    return 0;
}