about summary refs log tree commit diff
path: root/third_party/nix/src/libexpr/value-to-json.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/libexpr/value-to-json.cc')
-rw-r--r--third_party/nix/src/libexpr/value-to-json.cc104
1 files changed, 104 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..0b641a41b5ac
--- /dev/null
+++ b/third_party/nix/src/libexpr/value-to-json.cc
@@ -0,0 +1,104 @@
+#include "value-to-json.hh"
+
+#include <cstdlib>
+#include <iomanip>
+
+#include "eval-inline.hh"
+#include "json.hh"
+#include "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 tList1:
+    case tList2:
+    case tListN: {
+      auto list(out.list());
+      for (unsigned int n = 0; n < v.listSize(); ++n) {
+        auto placeholder(list.placeholder());
+        printValueAsJSON(state, strict, *v.listElems()[n], placeholder,
+                         context);
+      }
+      break;
+    }
+
+    case tExternal:
+      v.external->printValueAsJSON(state, strict, out, 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);
+}
+
+void ExternalValueBase::printValueAsJSON(EvalState& state, bool strict,
+                                         JSONPlaceholder& out,
+                                         PathSet& context) const {
+  throw TypeError(format("cannot convert %1% to JSON") % showType());
+}
+
+}  // namespace nix