mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-24 14:56:15 +02:00
ac89bb064a
All OS and IO operations should be moved out, leaving only some misc portable pure functions. This is useful to avoid copious CPP when doing things like Windows and Emscripten ports. Newly exposed functions to break cycles: - `restoreSignals` - `updateWindowSize`
126 lines
3.6 KiB
C++
126 lines
3.6 KiB
C++
#include "value-to-json.hh"
|
|
#include "eval-inline.hh"
|
|
#include "store-api.hh"
|
|
#include "signals.hh"
|
|
|
|
#include <cstdlib>
|
|
#include <iomanip>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
|
namespace nix {
|
|
using json = nlohmann::json;
|
|
json printValueAsJSON(EvalState & state, bool strict,
|
|
Value & v, const PosIdx pos, NixStringContext & context, bool copyToStore)
|
|
{
|
|
checkInterrupt();
|
|
|
|
if (strict) state.forceValue(v, pos);
|
|
|
|
json out;
|
|
|
|
switch (v.type()) {
|
|
|
|
case nInt:
|
|
out = v.integer;
|
|
break;
|
|
|
|
case nBool:
|
|
out = v.boolean;
|
|
break;
|
|
|
|
case nString:
|
|
copyContext(v, context);
|
|
out = v.c_str();
|
|
break;
|
|
|
|
case nPath:
|
|
if (copyToStore)
|
|
out = state.store->printStorePath(
|
|
state.copyPathToStore(context, v.path()));
|
|
else
|
|
out = v.path().path.abs();
|
|
break;
|
|
|
|
case nNull:
|
|
// already initialized as null
|
|
break;
|
|
|
|
case nAttrs: {
|
|
auto maybeString = state.tryAttrsToString(pos, v, context, false, false);
|
|
if (maybeString) {
|
|
out = *maybeString;
|
|
break;
|
|
}
|
|
auto i = v.attrs->find(state.sOutPath);
|
|
if (i == v.attrs->end()) {
|
|
out = json::object();
|
|
StringSet names;
|
|
for (auto & j : *v.attrs)
|
|
names.emplace(state.symbols[j.name]);
|
|
for (auto & j : names) {
|
|
Attr & a(*v.attrs->find(state.symbols.create(j)));
|
|
try {
|
|
out[j] = printValueAsJSON(state, strict, *a.value, a.pos, context, copyToStore);
|
|
} catch (Error & e) {
|
|
e.addTrace(state.positions[a.pos],
|
|
hintfmt("while evaluating attribute '%1%'", j));
|
|
throw;
|
|
}
|
|
}
|
|
} else
|
|
return printValueAsJSON(state, strict, *i->value, i->pos, context, copyToStore);
|
|
break;
|
|
}
|
|
|
|
case nList: {
|
|
out = json::array();
|
|
int i = 0;
|
|
for (auto elem : v.listItems()) {
|
|
try {
|
|
out.push_back(printValueAsJSON(state, strict, *elem, pos, context, copyToStore));
|
|
} catch (Error & e) {
|
|
e.addTrace({},
|
|
hintfmt("while evaluating list element at index %1%", i));
|
|
throw;
|
|
}
|
|
i++;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case nExternal:
|
|
return v.external->printValueAsJSON(state, strict, context, copyToStore);
|
|
break;
|
|
|
|
case nFloat:
|
|
out = v.fpoint;
|
|
break;
|
|
|
|
case nThunk:
|
|
case nFunction:
|
|
auto e = TypeError({
|
|
.msg = hintfmt("cannot convert %1% to JSON", showType(v)),
|
|
.errPos = state.positions[v.determinePos(pos)]
|
|
});
|
|
e.addTrace(state.positions[pos], hintfmt("message for the trace"));
|
|
state.debugThrowLastTrace(e);
|
|
throw e;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
void printValueAsJSON(EvalState & state, bool strict,
|
|
Value & v, const PosIdx pos, std::ostream & str, NixStringContext & context, bool copyToStore)
|
|
{
|
|
str << printValueAsJSON(state, strict, v, pos, context, copyToStore);
|
|
}
|
|
|
|
json ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
|
NixStringContext & context, bool copyToStore) const
|
|
{
|
|
state.debugThrowLastTrace(TypeError("cannot convert %1% to JSON", showType()));
|
|
}
|
|
|
|
|
|
}
|