about summary refs log tree commit diff
path: root/src/libexpr/value-to-json.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-08-26T16·55+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-08-29T15·29+0200
commitc0a7b84748d5e27e6804117b8a57ce71269c3c66 (patch)
tree40f22e1dd5636673f764bc1f289ab254971ca95d /src/libexpr/value-to-json.cc
parent9fa21765e7f267efcc65e1aa6ab21402ea6125ad (diff)
nix path-info: Add --json flag
Also, factor out JSON generation from value-to-json.{cc,hh}, and
support producing indented JSON.
Diffstat (limited to 'src/libexpr/value-to-json.cc')
-rw-r--r--src/libexpr/value-to-json.cc55
1 files changed, 23 insertions, 32 deletions
diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc
index 47ee324a6e..72e413e449 100644
--- a/src/libexpr/value-to-json.cc
+++ b/src/libexpr/value-to-json.cc
@@ -1,4 +1,5 @@
 #include "value-to-json.hh"
+#include "json.hh"
 #include "eval-inline.hh"
 #include "util.hh"
 
@@ -8,24 +9,8 @@
 
 namespace nix {
 
-
-void escapeJSON(std::ostream & str, const string & s)
-{
-    str << "\"";
-    for (auto & i : s)
-        if (i == '\"' || i == '\\') str << "\\" << i;
-        else if (i == '\n') str << "\\n";
-        else if (i == '\r') str << "\\r";
-        else if (i == '\t') str << "\\t";
-        else if (i >= 0 && i < 32)
-            str << "\\u" << std::setfill('0') << std::setw(4) << std::hex << (uint16_t) i << std::dec;
-        else str << i;
-    str << "\"";
-}
-
-
 void printValueAsJSON(EvalState & state, bool strict,
-    Value & v, std::ostream & str, PathSet & context)
+    Value & v, JSONPlaceholder & out, PathSet & context)
 {
     checkInterrupt();
 
@@ -34,58 +19,58 @@ void printValueAsJSON(EvalState & state, bool strict,
     switch (v.type) {
 
         case tInt:
-            str << v.integer;
+            out.write(v.integer);
             break;
 
         case tBool:
-            str << (v.boolean ? "true" : "false");
+            out.write(v.boolean);
             break;
 
         case tString:
             copyContext(v, context);
-            escapeJSON(str, v.string.s);
+            out.write(v.string.s);
             break;
 
         case tPath:
-            escapeJSON(str, state.copyPathToStore(context, v.path));
+            out.write(state.copyPathToStore(context, v.path));
             break;
 
         case tNull:
-            str << "null";
+            out.write(nullptr);
             break;
 
         case tAttrs: {
             Bindings::iterator i = v.attrs->find(state.sOutPath);
             if (i == v.attrs->end()) {
-                JSONObject json(str);
+                auto obj(out.object());
                 StringSet names;
                 for (auto & j : *v.attrs)
                     names.insert(j.name);
                 for (auto & j : names) {
                     Attr & a(*v.attrs->find(state.symbols.create(j)));
-                    json.attr(j);
-                    printValueAsJSON(state, strict, *a.value, str, context);
+                    auto placeholder(obj.placeholder(j));
+                    printValueAsJSON(state, strict, *a.value, placeholder, context);
                 }
             } else
-                printValueAsJSON(state, strict, *i->value, str, context);
+                printValueAsJSON(state, strict, *i->value, out, context);
             break;
         }
 
         case tList1: case tList2: case tListN: {
-            JSONList json(str);
+            auto list(out.list());
             for (unsigned int n = 0; n < v.listSize(); ++n) {
-                json.elem();
-                printValueAsJSON(state, strict, *v.listElems()[n], str, context);
+                auto placeholder(list.placeholder());
+                printValueAsJSON(state, strict, *v.listElems()[n], placeholder, context);
             }
             break;
         }
 
         case tExternal:
-            v.external->printValueAsJSON(state, strict, str, context);
+            v.external->printValueAsJSON(state, strict, out, context);
             break;
 
         case tFloat:
-            str << v.fpoint;
+            out.write(v.fpoint);
             break;
 
         default:
@@ -93,9 +78,15 @@ void printValueAsJSON(EvalState & state, bool strict,
     }
 }
 
+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,
-      std::ostream & str, PathSet & context) const
+    JSONPlaceholder & out, PathSet & context) const
 {
     throw TypeError(format("cannot convert %1% to JSON") % showType());
 }