| ... | @@ -21,14 +21,10 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { | ... | @@ -21,14 +21,10 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { |
| 21 | | 21 | |
| 22 | pub const Stream = OutStream; | 22 | pub const Stream = OutStream; |
| 23 | | 23 | |
| 24 | /// The string used for indenting. | 24 | whitespace: std.json.StringifyOptions.Whitespace = std.json.StringifyOptions.Whitespace{ |
| 25 | one_indent: []const u8 = " ", | 25 | .indent_level = 0, |
| 26 | | 26 | .indent = .{ .Space = 1 }, |
| 27 | /// The string used as a newline character. | 27 | }, |
| 28 | newline: []const u8 = "\n", | | |
| 29 | | | |
| 30 | /// The string used as spacing. | | |
| 31 | space: []const u8 = " ", | | |
| 32 | | 28 | |
| 33 | stream: OutStream, | 29 | stream: OutStream, |
| 34 | state_index: usize, | 30 | state_index: usize, |
| ... | @@ -49,12 +45,14 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { | ... | @@ -49,12 +45,14 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { |
| 49 | assert(self.state[self.state_index] == State.Value); // need to call arrayElem or objectField | 45 | assert(self.state[self.state_index] == State.Value); // need to call arrayElem or objectField |
| 50 | try self.stream.writeByte('['); | 46 | try self.stream.writeByte('['); |
| 51 | self.state[self.state_index] = State.ArrayStart; | 47 | self.state[self.state_index] = State.ArrayStart; |
| | 48 | self.whitespace.indent_level += 1; |
| 52 | } | 49 | } |
| 53 | | 50 | |
| 54 | pub fn beginObject(self: *Self) !void { | 51 | pub fn beginObject(self: *Self) !void { |
| 55 | assert(self.state[self.state_index] == State.Value); // need to call arrayElem or objectField | 52 | assert(self.state[self.state_index] == State.Value); // need to call arrayElem or objectField |
| 56 | try self.stream.writeByte('{'); | 53 | try self.stream.writeByte('{'); |
| 57 | self.state[self.state_index] = State.ObjectStart; | 54 | self.state[self.state_index] = State.ObjectStart; |
| | 55 | self.whitespace.indent_level += 1; |
| 58 | } | 56 | } |
| 59 | | 57 | |
| 60 | pub fn arrayElem(self: *Self) !void { | 58 | pub fn arrayElem(self: *Self) !void { |
| ... | @@ -90,8 +88,10 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { | ... | @@ -90,8 +88,10 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { |
| 90 | self.pushState(.Value); | 88 | self.pushState(.Value); |
| 91 | try self.indent(); | 89 | try self.indent(); |
| 92 | try self.writeEscapedString(name); | 90 | try self.writeEscapedString(name); |
| 93 | try self.stream.writeAll(":"); | 91 | try self.stream.writeByte(':'); |
| 94 | try self.stream.writeAll(self.space); | 92 | if (self.whitespace.separator) { |
| | 93 | try self.stream.writeByte(' '); |
| | 94 | } |
| 95 | }, | 95 | }, |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| ... | @@ -103,10 +103,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { | ... | @@ -103,10 +103,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { |
| 103 | .ObjectStart => unreachable, | 103 | .ObjectStart => unreachable, |
| 104 | .Object => unreachable, | 104 | .Object => unreachable, |
| 105 | .ArrayStart => { | 105 | .ArrayStart => { |
| | 106 | self.whitespace.indent_level -= 1; |
| 106 | try self.stream.writeByte(']'); | 107 | try self.stream.writeByte(']'); |
| 107 | self.popState(); | 108 | self.popState(); |
| 108 | }, | 109 | }, |
| 109 | .Array => { | 110 | .Array => { |
| | 111 | self.whitespace.indent_level -= 1; |
| 110 | try self.indent(); | 112 | try self.indent(); |
| 111 | self.popState(); | 113 | self.popState(); |
| 112 | try self.stream.writeByte(']'); | 114 | try self.stream.writeByte(']'); |
| ... | @@ -121,10 +123,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { | ... | @@ -121,10 +123,12 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { |
| 121 | .ArrayStart => unreachable, | 123 | .ArrayStart => unreachable, |
| 122 | .Array => unreachable, | 124 | .Array => unreachable, |
| 123 | .ObjectStart => { | 125 | .ObjectStart => { |
| | 126 | self.whitespace.indent_level -= 1; |
| 124 | try self.stream.writeByte('}'); | 127 | try self.stream.writeByte('}'); |
| 125 | self.popState(); | 128 | self.popState(); |
| 126 | }, | 129 | }, |
| 127 | .Object => { | 130 | .Object => { |
| | 131 | self.whitespace.indent_level -= 1; |
| 128 | try self.indent(); | 132 | try self.indent(); |
| 129 | self.popState(); | 133 | self.popState(); |
| 130 | try self.stream.writeByte('}'); | 134 | try self.stream.writeByte('}'); |
| ... | @@ -187,39 +191,15 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { | ... | @@ -187,39 +191,15 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type { |
| 187 | | 191 | |
| 188 | /// Writes the complete json into the output stream | 192 | /// Writes the complete json into the output stream |
| 189 | pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void { | 193 | pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void { |
| 190 | switch (json) { | 194 | try json.jsonStringify(std.json.StringifyOptions{ |
| 191 | .Null => try self.emitNull(), | 195 | .whitespace = self.whitespace, |
| 192 | .Bool => |inner| try self.emitBool(inner), | 196 | }, self.stream); |
| 193 | .Integer => |inner| try self.emitNumber(inner), | | |
| 194 | .Float => |inner| try self.emitNumber(inner), | | |
| 195 | .String => |inner| try self.emitString(inner), | | |
| 196 | .Array => |inner| { | | |
| 197 | try self.beginArray(); | | |
| 198 | for (inner.span()) |elem| { | | |
| 199 | try self.arrayElem(); | | |
| 200 | try self.emitJson(elem); | | |
| 201 | } | | |
| 202 | try self.endArray(); | | |
| 203 | }, | | |
| 204 | .Object => |inner| { | | |
| 205 | try self.beginObject(); | | |
| 206 | var it = inner.iterator(); | | |
| 207 | while (it.next()) |entry| { | | |
| 208 | try self.objectField(entry.key); | | |
| 209 | try self.emitJson(entry.value); | | |
| 210 | } | | |
| 211 | try self.endObject(); | | |
| 212 | }, | | |
| 213 | } | | |
| 214 | } | 197 | } |
| 215 | | 198 | |
| 216 | fn indent(self: *Self) !void { | 199 | fn indent(self: *Self) !void { |
| 217 | assert(self.state_index >= 1); | 200 | assert(self.state_index >= 1); |
| 218 | try self.stream.writeAll(self.newline); | 201 | try self.stream.writeByte('\n'); |
| 219 | var i: usize = 0; | 202 | try self.whitespace.outputIndent(self.stream); |
| 220 | while (i < self.state_index - 1) : (i += 1) { | | |
| 221 | try self.stream.writeAll(self.one_indent); | | |
| 222 | } | | |
| 223 | } | 203 | } |
| 224 | | 204 | |
| 225 | fn pushState(self: *Self, state: State) void { | 205 | fn pushState(self: *Self, state: State) void { |