From b82b6a70933fd6ba3ec942811bb0171e3414632e Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Thu, 24 Oct 2019 14:23:36 +0200 Subject: [PATCH 1/4] Added 'writeJson' to write_stream.zig: Small addition to make writing a json value easier --- lib/std/json/write_stream.zig | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index c30f8ba8d8..c99edef113 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -197,6 +197,34 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { try self.stream.writeByte('"'); } + /// Writes the complete json into the output stream + pub fn writeJson(self: *Self, json: std.json.Value) std.os.WriteError!void { + switch (json) { + std.json.Value.Null => try self.emitNull(), + std.json.Value.Bool => |inner| try self.emitBool(inner), + std.json.Value.Integer => |inner| try self.emitNumber(inner), + std.json.Value.Float => |inner| try self.emitNumber(inner), + std.json.Value.String => |inner| try self.emitString(inner), + std.json.Value.Array => |inner| { + try self.beginArray(); + for (inner.toSliceConst()) |elem| { + try self.arrayElem(); + try self.writeJson(elem); + } + try self.endArray(); + }, + std.json.Value.Object => |inner| { + try self.beginObject(); + var it = inner.iterator(); + while (it.next()) |entry| { + try self.objectField(entry.key); + try self.writeJson(entry.value); + } + try self.endObject(); + }, + } + } + fn indent(self: *Self) !void { assert(self.state_index >= 1); try self.stream.write(self.newline); From 6257b4c5967e8153fc055025f712be6d0f7fc78b Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Thu, 24 Oct 2019 22:44:12 +0200 Subject: [PATCH 2/4] Shortened switch statement --- lib/std/json/write_stream.zig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index c99edef113..817ba3dd5b 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -200,12 +200,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { /// Writes the complete json into the output stream pub fn writeJson(self: *Self, json: std.json.Value) std.os.WriteError!void { switch (json) { - std.json.Value.Null => try self.emitNull(), - std.json.Value.Bool => |inner| try self.emitBool(inner), - std.json.Value.Integer => |inner| try self.emitNumber(inner), - std.json.Value.Float => |inner| try self.emitNumber(inner), - std.json.Value.String => |inner| try self.emitString(inner), - std.json.Value.Array => |inner| { + .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.toSliceConst()) |elem| { try self.arrayElem(); @@ -213,7 +213,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { } try self.endArray(); }, - std.json.Value.Object => |inner| { + .Object => |inner| { try self.beginObject(); var it = inner.iterator(); while (it.next()) |entry| { From ac705a7bb6ddafa1a8a7bfafe9e61f1246da8408 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Sun, 27 Oct 2019 20:15:48 +0100 Subject: [PATCH 3/4] Unified public api --- lib/std/json/write_stream.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index 817ba3dd5b..bfa5647855 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -198,7 +198,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { } /// Writes the complete json into the output stream - pub fn writeJson(self: *Self, json: std.json.Value) std.os.WriteError!void { + pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void { switch (json) { .Null => try self.emitNull(), .Bool => |inner| try self.emitBool(inner), @@ -209,7 +209,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { try self.beginArray(); for (inner.toSliceConst()) |elem| { try self.arrayElem(); - try self.writeJson(elem); + try self.emitJson(elem); } try self.endArray(); }, @@ -218,7 +218,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { var it = inner.iterator(); while (it.next()) |entry| { try self.objectField(entry.key); - try self.writeJson(entry.value); + try self.emitJson(entry.value); } try self.endObject(); }, From 78b00c0b5117467d03c85d476b872fe96f767829 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Sun, 27 Oct 2019 20:49:42 +0100 Subject: [PATCH 4/4] Added test for 'emitJson' --- lib/std/json.zig | 1 + lib/std/json/write_stream.zig | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/lib/std/json.zig b/lib/std/json.zig index 07916ff842..025cf28a70 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1407,6 +1407,7 @@ test "json.parser.dynamic" { test "import more json tests" { _ = @import("json/test.zig"); + _ = @import("json/write_stream.zig"); } test "write json then parse it" { diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig index bfa5647855..0702a3e9f5 100644 --- a/lib/std/json/write_stream.zig +++ b/lib/std/json/write_stream.zig @@ -244,3 +244,61 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { } }; } + +test "json write stream" { + var out_buf: [1024]u8 = undefined; + var slice_stream = std.io.SliceOutStream.init(&out_buf); + const out = &slice_stream.stream; + + var mem_buf: [1024 * 10]u8 = undefined; + const allocator = &std.heap.FixedBufferAllocator.init(&mem_buf).allocator; + + var w = std.json.WriteStream(@typeOf(out).Child, 10).init(out); + try w.emitJson(try getJson(allocator)); + + const result = slice_stream.getWritten(); + const expected = + \\{ + \\ "object": { + \\ "one": 1, + \\ "two": 2.0e+00 + \\ }, + \\ "string": "This is a string", + \\ "array": [ + \\ "Another string", + \\ 1, + \\ 3.14e+00 + \\ ], + \\ "int": 10, + \\ "float": 3.14e+00 + \\} + ; + std.testing.expect(std.mem.eql(u8, expected, result)); +} + +fn getJson(allocator: *std.mem.Allocator) !std.json.Value { + var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) }; + _ = try value.Object.put("string", std.json.Value{ .String = "This is a string" }); + _ = try value.Object.put("int", std.json.Value{ .Integer = @intCast(i64, 10) }); + _ = try value.Object.put("float", std.json.Value{ .Float = 3.14 }); + _ = try value.Object.put("array", try getJsonArray(allocator)); + _ = try value.Object.put("object", try getJsonObject(allocator)); + return value; +} + +fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value { + var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) }; + _ = try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) }); + _ = try value.Object.put("two", std.json.Value{ .Float = 2.0 }); + return value; +} + +fn getJsonArray(allocator: *std.mem.Allocator) !std.json.Value { + var value = std.json.Value{ .Array = std.json.Array.init(allocator) }; + var array = &value.Array; + _ = try array.append(std.json.Value{ .String = "Another string" }); + _ = try array.append(std.json.Value{ .Integer = @intCast(i64, 1) }); + _ = try array.append(std.json.Value{ .Float = 3.14 }); + + return value; +}