commit 8af6c7e34ceebde898d32bb50aaee5faac538af2 (tree)
parent f756d875b12f0fa18d9fa3eaa4d15edb56dd0275
Author: Andrew Kelley <andrew@ziglang.org>
Date: Sun, 27 Oct 2019 15:53:24 -0400
Merge pull request #3522 from SebastianKeller/WriteJson
Added 'writeJson' to write_stream.zig:
Diffstat:
2 files changed, 87 insertions(+), 0 deletions(-)
diff --git 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
@@ -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 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.toSliceConst()) |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();
+ },
+ }
+ }
+
fn indent(self: *Self) !void {
assert(self.state_index >= 1);
try self.stream.write(self.newline);
@@ -216,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;
+}