Commit f81f36e2ff

Sebastian Keller <sebastiankeller@fastmail.net>
2019-10-28 21:33:40
std.json.Value: added dumpStream(), utilize WriteStream for dump()
1 parent ac6f0d2
Changed files (3)
lib/std/json/write_stream.zig
@@ -27,6 +27,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
         /// The string used as a newline character.
         newline: []const u8 = "\n",
 
+        /// The string used as spacing.
+        space: []const u8 = " ",
+
         stream: *OutStream,
         state_index: usize,
         state: [max_depth]State,
@@ -87,7 +90,8 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
                     self.pushState(.Value);
                     try self.indent();
                     try self.writeEscapedString(name);
-                    try self.stream.write(": ");
+                    try self.stream.write(":");
+                    try self.stream.write(self.space);
                 },
             }
         }
lib/std/debug.zig
@@ -45,6 +45,7 @@ var stderr_file_out_stream: File.OutStream = undefined;
 
 var stderr_stream: ?*io.OutStream(File.WriteError) = null;
 var stderr_mutex = std.Mutex.init();
+
 pub fn warn(comptime fmt: []const u8, args: ...) void {
     const held = stderr_mutex.acquire();
     defer held.release();
@@ -64,6 +65,10 @@ pub fn getStderrStream() !*io.OutStream(File.WriteError) {
     }
 }
 
+pub fn getStderrMutex() *std.Mutex {
+    return &stderr_mutex;
+}
+
 /// TODO multithreaded awareness
 var self_debug_info: ?DebugInfo = null;
 
lib/std/json.zig
@@ -1012,119 +1012,39 @@ pub const Value = union(enum) {
     Object: ObjectMap,
 
     pub fn dump(self: Value) void {
-        switch (self) {
-            Value.Null => {
-                debug.warn("null");
-            },
-            Value.Bool => |inner| {
-                debug.warn("{}", inner);
-            },
-            Value.Integer => |inner| {
-                debug.warn("{}", inner);
-            },
-            Value.Float => |inner| {
-                debug.warn("{:.5}", inner);
-            },
-            Value.String => |inner| {
-                debug.warn("\"{}\"", inner);
-            },
-            Value.Array => |inner| {
-                var not_first = false;
-                debug.warn("[");
-                for (inner.toSliceConst()) |value| {
-                    if (not_first) {
-                        debug.warn(",");
-                    }
-                    not_first = true;
-                    value.dump();
-                }
-                debug.warn("]");
-            },
-            Value.Object => |inner| {
-                var not_first = false;
-                debug.warn("{{");
-                var it = inner.iterator();
-
-                while (it.next()) |entry| {
-                    if (not_first) {
-                        debug.warn(",");
-                    }
-                    not_first = true;
-                    debug.warn("\"{}\":", entry.key);
-                    entry.value.dump();
-                }
-                debug.warn("}}");
-            },
-        }
+        var held = std.debug.getStderrMutex().acquire();
+        defer held.release();
+
+        const stderr = std.debug.getStderrStream() catch return;
+        self.dumpStream(stderr, 1024) catch return;
     }
 
-    pub fn dumpIndent(self: Value, indent: usize) void {
+    pub fn dumpIndent(self: Value, comptime indent: usize) void {
         if (indent == 0) {
             self.dump();
         } else {
-            self.dumpIndentLevel(indent, 0);
+            var held = std.debug.getStderrMutex().acquire();
+            defer held.release();
+
+            const stderr = std.debug.getStderrStream() catch return;
+            self.dumpStreamIndent(indent, stderr, 1024) catch return;
         }
     }
 
-    fn dumpIndentLevel(self: Value, indent: usize, level: usize) void {
-        switch (self) {
-            Value.Null => {
-                debug.warn("null");
-            },
-            Value.Bool => |inner| {
-                debug.warn("{}", inner);
-            },
-            Value.Integer => |inner| {
-                debug.warn("{}", inner);
-            },
-            Value.Float => |inner| {
-                debug.warn("{:.5}", inner);
-            },
-            Value.String => |inner| {
-                debug.warn("\"{}\"", inner);
-            },
-            Value.Array => |inner| {
-                var not_first = false;
-                debug.warn("[\n");
-
-                for (inner.toSliceConst()) |value| {
-                    if (not_first) {
-                        debug.warn(",\n");
-                    }
-                    not_first = true;
-                    padSpace(level + indent);
-                    value.dumpIndentLevel(indent, level + indent);
-                }
-                debug.warn("\n");
-                padSpace(level);
-                debug.warn("]");
-            },
-            Value.Object => |inner| {
-                var not_first = false;
-                debug.warn("{{\n");
-                var it = inner.iterator();
-
-                while (it.next()) |entry| {
-                    if (not_first) {
-                        debug.warn(",\n");
-                    }
-                    not_first = true;
-                    padSpace(level + indent);
-                    debug.warn("\"{}\": ", entry.key);
-                    entry.value.dumpIndentLevel(indent, level + indent);
-                }
-                debug.warn("\n");
-                padSpace(level);
-                debug.warn("}}");
-            },
-        }
+    pub fn dumpStream(self: @This(), stream: var, comptime max_depth: usize) !void {
+        var w = std.json.WriteStream(@typeOf(stream).Child, max_depth).init(stream);
+        w.newline = "";
+        w.one_indent = "";
+        w.space = "";
+        try w.emitJson(self);
     }
 
-    fn padSpace(indent: usize) void {
-        var i: usize = 0;
-        while (i < indent) : (i += 1) {
-            debug.warn(" ");
-        }
+    pub fn dumpStreamIndent(self: @This(), comptime indent: usize, stream: var, comptime max_depth: usize) !void {
+        var one_indent = " " ** indent;
+
+        var w = std.json.WriteStream(@typeOf(stream).Child, max_depth).init(stream);
+        w.one_indent = one_indent;
+        try w.emitJson(self);
     }
 };