mirror of
https://github.com/NixOS/nix
synced 2025-06-26 20:01:15 +02:00
Add a fromTOML primop
This is primarily useful for processing Cargo.lock files.
This commit is contained in:
parent
a92ed973e5
commit
3b1f54cf06
4 changed files with 280 additions and 0 deletions
77
src/libexpr/primops/fromTOML.cc
Normal file
77
src/libexpr/primops/fromTOML.cc
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "primops.hh"
|
||||
#include "eval-inline.hh"
|
||||
|
||||
#include <cpptoml.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
using namespace cpptoml;
|
||||
|
||||
auto toml = state.forceStringNoCtx(*args[0], pos);
|
||||
|
||||
std::istringstream tomlStream(toml);
|
||||
|
||||
std::function<void(Value &, std::shared_ptr<base>)> visit;
|
||||
|
||||
visit = [&](Value & v, std::shared_ptr<base> t) {
|
||||
|
||||
if (auto t2 = t->as_table()) {
|
||||
|
||||
size_t size = 0;
|
||||
for (auto & i : *t2) size++;
|
||||
|
||||
state.mkAttrs(v, size);
|
||||
|
||||
for (auto & i : *t2) {
|
||||
auto & v2 = *state.allocAttr(v, state.symbols.create(i.first));
|
||||
|
||||
if (auto i2 = i.second->as_table_array()) {
|
||||
size_t size2 = i2->get().size();
|
||||
state.mkList(v2, size2);
|
||||
for (size_t j = 0; j < size2; ++j)
|
||||
visit(*(v2.listElems()[j] = state.allocValue()), i2->get()[j]);
|
||||
}
|
||||
else
|
||||
visit(v2, i.second);
|
||||
}
|
||||
|
||||
v.attrs->sort();
|
||||
}
|
||||
|
||||
else if (auto t2 = t->as_array()) {
|
||||
size_t size = t2->get().size();
|
||||
|
||||
state.mkList(v, size);
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
visit(*(v.listElems()[i] = state.allocValue()), t2->get()[i]);
|
||||
}
|
||||
|
||||
else if (t->is_value()) {
|
||||
if (auto val = t->as<NixInt>())
|
||||
mkInt(v, val->get());
|
||||
else if (auto val = t->as<NixFloat>())
|
||||
mkFloat(v, val->get());
|
||||
else if (auto val = t->as<bool>())
|
||||
mkBool(v, val->get());
|
||||
else if (auto val = t->as<std::string>())
|
||||
mkString(v, val->get());
|
||||
else
|
||||
throw EvalError("unsupported value type in TOML");
|
||||
}
|
||||
|
||||
else abort();
|
||||
};
|
||||
|
||||
try {
|
||||
visit(v, parser(tomlStream).parse());
|
||||
} catch (std::runtime_error & e) {
|
||||
throw EvalError("while parsing a TOML string at %s: %s", pos, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
static RegisterPrimOp r("fromTOML", 1, prim_fromTOML);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue