query
On this page

fromTOML

builtins.fromTOML

Primop
Docs pulled from | This Revision | about 4 hours ago


Nix manual

Takes 1 arguments

e

Convert a TOML string to a Nix value. For example,

builtins.fromTOML ''
  x=1
  s="a"
  [table]
  y=2
''

returns the value { s = "a"; table = { y = 2; }; x = 1; }.

Noogle detected

Aliases

Detected Type
fromTOML :: String -> AttrSet

Implementation

This function is implemented in c++ and is part of the native nix runtime.

src/libexpr/primops/fromTOML.cc:90

static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Value & val)
{
    auto toml = state.forceStringNoCtx(*args[0], pos, "while evaluating the argument passed to builtins.fromTOML");

    std::istringstream tomlStream(std::string{toml});

    auto visit = [&](this auto & self, Value & v, toml::value t) -> void {
        switch (t.type()) {
        case toml::value_t::table: {
            auto table = toml::get<toml::table>(t);
            auto attrs = state.buildBindings(table.size());

            for (auto & elem : table) {
                forceNoNullByte(elem.first);
                self(attrs.alloc(elem.first), elem.second);
            }

            v.mkAttrs(attrs);
        } break;
        case toml::value_t::array: {
            auto array = toml::get<std::vector<toml::value>>(t);

            auto list = state.buildList(array.size());
            for (const auto & [n, v] : enumerate(list))
                self(*(v = state.allocValue()), array[n]);
            v.mkList(list);
        } break;
        case toml::value_t::boolean:
            v.mkBool(toml::get<bool>(t));
            break;
        case toml::value_t::integer:
            v.mkInt(toml::get<int64_t>(t));
            break;
        case toml::value_t::floating:
            v.mkFloat(toml::get<NixFloat>(t));
            break;
        case toml::value_t::string: {
            auto s = toml::get<std::string_view>(t);
            forceNoNullByte(s);
            v.mkString(s, state.mem);
        } break;
        case toml::value_t::local_datetime:
        case toml::value_t::offset_datetime:
        case toml::value_t::local_date:
        case toml::value_t::local_time: {
            if (experimentalFeatureSettings.isEnabled(Xp::ParseTomlTimestamps)) {
#if HAVE_TOML11_4
                normalizeDatetimeFormat(t);
#endif
                auto attrs = state.buildBindings(2);
                attrs.alloc("_type").mkStringNoCopy("timestamp"_sds);
                std::ostringstream s;
                s << t;
                auto str = s.view();
                forceNoNullByte(str);
                attrs.alloc("value").mkString(str, state.mem);
                v.mkAttrs(attrs);
            } else {
                throw std::runtime_error("Dates and times are not supported");
            }
        } break;
        case toml::value_t::empty:
            v.mkNull();
            break;
        }
    };

    try {
        visit(
            val,
            toml::parse(
                tomlStream,
                "fromTOML" /* the "filename" */
#if HAVE_TOML11_4
                ,
                toml::spec::v(1, 0, 0) // Be explicit that we are parsing TOML 1.0.0 without extensions
#endif
                ));
    } catch (std::exception & e) { // TODO: toml::syntax_error
        state.error<EvalError>("while parsing TOML: %s", e.what()).atPos(pos).debugThrow();
    }
}