#include "primops.hh" #include "eval-inline.hh" #include "../../toml11/toml.hpp" namespace nix { static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Value & val) { auto toml = state.forceStringNoCtx(*args[0], pos); std::istringstream tomlStream(toml); std::function visit; visit = [&](Value & v, toml::value t) { switch(t.type()) { case toml::value_t::table: { auto table = toml::get(t); size_t size = 0; for (auto & i : table) { (void) i; size++; } state.mkAttrs(v, size); for(auto & elem: table) { auto & v2 = *state.allocAttr(v, state.symbols.create(elem.first)); visit(v2, elem.second); } v.attrs->sort(); } break;; case toml::value_t::array: { auto array = toml::get>(t); size_t size = array.size(); state.mkList(v, size); for (size_t i = 0; i < size; ++i) visit(*(v.listElems()[i] = state.allocValue()), array[i]); } break;; case toml::value_t::boolean: mkBool(v, toml::get(t)); break;; case toml::value_t::integer: mkInt(v, toml::get(t)); break;; case toml::value_t::floating: mkFloat(v, toml::get(t)); break;; case toml::value_t::string: mkString(v, toml::get(t)); 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: // We fail since Nix doesn't have date and time types throw std::runtime_error("Dates and times are not supported"); break;; case toml::value_t::empty: mkNull(v); break;; } }; try { visit(val, toml::parse(tomlStream, "fromTOML" /* the "filename" */)); } catch (std::exception & e) { // TODO: toml::syntax_error throw EvalError({ .msg = hintfmt("while parsing a TOML string: %s", e.what()), .errPos = pos }); } } static RegisterPrimOp primop_fromTOML("fromTOML", 1, prim_fromTOML); }