diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-03-31 12:07:25 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-31 12:07:25 -0400 |
| commit | d34a3c66b36e3afc8ea7f275b449033fa7a1b4bc (patch) | |
| tree | 295a4ad2b0e6cec0c19c5807f18daced97cd3dd6 /lib/std/json/write_stream.zig | |
| parent | 28b7306a31f52f53e7936018c01c0e8d24ebf6ea (diff) | |
| parent | 7a3d700fd9d6dcdb559aaae9159af6725b28defb (diff) | |
| download | zig-d34a3c66b36e3afc8ea7f275b449033fa7a1b4bc.tar.gz zig-d34a3c66b36e3afc8ea7f275b449033fa7a1b4bc.zip | |
Merge pull request #4543 from daurnimator/cleanup-json
std.json improvements
Diffstat (limited to 'lib/std/json/write_stream.zig')
| -rw-r--r-- | lib/std/json/write_stream.zig | 86 |
1 files changed, 27 insertions, 59 deletions
diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index cbe556dcfc..60974a207e 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -21,14 +21,10 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { pub const Stream = OutStream; - /// The string used for indenting. - one_indent: []const u8 = " ", - - /// The string used as a newline character. - newline: []const u8 = "\n", - - /// The string used as spacing. - space: []const u8 = " ", + whitespace: std.json.StringifyOptions.Whitespace = std.json.StringifyOptions.Whitespace{ + .indent_level = 0, + .indent = .{ .Space = 1 }, + }, stream: OutStream, state_index: usize, @@ -49,12 +45,14 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { assert(self.state[self.state_index] == State.Value); // need to call arrayElem or objectField try self.stream.writeByte('['); self.state[self.state_index] = State.ArrayStart; + self.whitespace.indent_level += 1; } pub fn beginObject(self: *Self) !void { assert(self.state[self.state_index] == State.Value); // need to call arrayElem or objectField try self.stream.writeByte('{'); self.state[self.state_index] = State.ObjectStart; + self.whitespace.indent_level += 1; } pub fn arrayElem(self: *Self) !void { @@ -90,8 +88,10 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { self.pushState(.Value); try self.indent(); try self.writeEscapedString(name); - try self.stream.writeAll(":"); - try self.stream.writeAll(self.space); + try self.stream.writeByte(':'); + if (self.whitespace.separator) { + try self.stream.writeByte(' '); + } }, } } @@ -103,10 +103,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { .ObjectStart => unreachable, .Object => unreachable, .ArrayStart => { + self.whitespace.indent_level -= 1; try self.stream.writeByte(']'); self.popState(); }, .Array => { + self.whitespace.indent_level -= 1; try self.indent(); self.popState(); try self.stream.writeByte(']'); @@ -121,10 +123,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { .ArrayStart => unreachable, .Array => unreachable, .ObjectStart => { + self.whitespace.indent_level -= 1; try self.stream.writeByte('}'); self.popState(); }, .Object => { + self.whitespace.indent_level -= 1; try self.indent(); self.popState(); try self.stream.writeByte('}'); @@ -134,17 +138,13 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { pub fn emitNull(self: *Self) !void { assert(self.state[self.state_index] == State.Value); - try self.stream.writeAll("null"); + try self.stringify(null); self.popState(); } pub fn emitBool(self: *Self, value: bool) !void { assert(self.state[self.state_index] == State.Value); - if (value) { - try self.stream.writeAll("true"); - } else { - try self.stream.writeAll("false"); - } + try self.stringify(value); self.popState(); } @@ -185,57 +185,19 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { } fn writeEscapedString(self: *Self, string: []const u8) !void { - try self.stream.writeByte('"'); - for (string) |s| { - switch (s) { - '"' => try self.stream.writeAll("\\\""), - '\t' => try self.stream.writeAll("\\t"), - '\r' => try self.stream.writeAll("\\r"), - '\n' => try self.stream.writeAll("\\n"), - 8 => try self.stream.writeAll("\\b"), - 12 => try self.stream.writeAll("\\f"), - '\\' => try self.stream.writeAll("\\\\"), - else => try self.stream.writeByte(s), - } - } - try self.stream.writeByte('"'); + assert(std.unicode.utf8ValidateSlice(string)); + try self.stringify(string); } /// Writes the complete json into the output stream pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void { - switch (json) { - .Null => try self.emitNull(), - .Bool => |inner| try self.emitBool(inner), - .Integer => |inner| try self.emitNumber(inner), - .Float => |inner| try self.emitNumber(inner), - .String => |inner| try self.emitString(inner), - .Array => |inner| { - try self.beginArray(); - for (inner.span()) |elem| { - try self.arrayElem(); - try self.emitJson(elem); - } - try self.endArray(); - }, - .Object => |inner| { - try self.beginObject(); - var it = inner.iterator(); - while (it.next()) |entry| { - try self.objectField(entry.key); - try self.emitJson(entry.value); - } - try self.endObject(); - }, - } + try self.stringify(json); } fn indent(self: *Self) !void { assert(self.state_index >= 1); - try self.stream.writeAll(self.newline); - var i: usize = 0; - while (i < self.state_index - 1) : (i += 1) { - try self.stream.writeAll(self.one_indent); - } + try self.stream.writeByte('\n'); + try self.whitespace.outputIndent(self.stream); } fn pushState(self: *Self, state: State) void { @@ -246,6 +208,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { fn popState(self: *Self) void { self.state_index -= 1; } + + fn stringify(self: *Self, value: var) !void { + try std.json.stringify(value, std.json.StringifyOptions{ + .whitespace = self.whitespace, + }, self.stream); + } }; } |
