diff options
Diffstat (limited to 'third_party/nix/src/libexpr/value-to-json.cc')
-rw-r--r-- | third_party/nix/src/libexpr/value-to-json.cc | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/third_party/nix/src/libexpr/value-to-json.cc b/third_party/nix/src/libexpr/value-to-json.cc new file mode 100644 index 000000000000..a338d4eed79a --- /dev/null +++ b/third_party/nix/src/libexpr/value-to-json.cc @@ -0,0 +1,91 @@ +#include "libexpr/value-to-json.hh" + +#include <cstdlib> +#include <iomanip> + +#include "libexpr/eval-inline.hh" +#include "libutil/json.hh" +#include "libutil/util.hh" + +namespace nix { + +void printValueAsJSON(EvalState& state, bool strict, Value& v, + JSONPlaceholder& out, PathSet& context) { + checkInterrupt(); + + if (strict) { + state.forceValue(v); + } + + switch (v.type) { + case tInt: + out.write(v.integer); + break; + + case tBool: + out.write(v.boolean); + break; + + case tString: + copyContext(v, context); + out.write(v.string.s); + break; + + case tPath: + out.write(state.copyPathToStore(context, v.path)); + break; + + case tNull: + out.write(nullptr); + break; + + case tAttrs: { + auto maybeString = + state.tryAttrsToString(noPos, v, context, false, false); + if (maybeString) { + out.write(*maybeString); + break; + } + auto i = v.attrs->find(state.sOutPath); + if (i == v.attrs->end()) { + auto obj(out.object()); + StringSet names; + for (auto& j : *v.attrs) { + names.insert(j.second.name); + } + for (auto& j : names) { + auto [_, a] = *v.attrs->find(state.symbols.Create(j)); + auto placeholder(obj.placeholder(j)); + printValueAsJSON(state, strict, *a.value, placeholder, context); + } + } else { + printValueAsJSON(state, strict, *i->second.value, out, context); + } + break; + } + + case tList: { + auto list(out.list()); + for (unsigned int n = 0; n < v.listSize(); ++n) { + auto placeholder(list.placeholder()); + printValueAsJSON(state, strict, *(*v.list)[n], placeholder, context); + } + break; + } + + case tFloat: + out.write(v.fpoint); + break; + + default: + throw TypeError(format("cannot convert %1% to JSON") % showType(v)); + } +} + +void printValueAsJSON(EvalState& state, bool strict, Value& v, + std::ostream& str, PathSet& context) { + JSONPlaceholder out(str); + printValueAsJSON(state, strict, v, out, context); +} + +} // namespace nix |