aboutsummaryrefslogtreecommitdiff
path: root/lib/std/json/write_stream.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-03-31 12:07:25 -0400
committerGitHub <noreply@github.com>2020-03-31 12:07:25 -0400
commitd34a3c66b36e3afc8ea7f275b449033fa7a1b4bc (patch)
tree295a4ad2b0e6cec0c19c5807f18daced97cd3dd6 /lib/std/json/write_stream.zig
parent28b7306a31f52f53e7936018c01c0e8d24ebf6ea (diff)
parent7a3d700fd9d6dcdb559aaae9159af6725b28defb (diff)
downloadzig-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.zig86
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);
+ }
};
}