Commit 10a671ad09
Changed files (1)
lib
std
lib/std/json.zig
@@ -2963,6 +2963,47 @@ fn outputUnicodeEscape(
}
}
+fn outputJsonString(value: []const u8, options: StringifyOptions, out_stream: anytype) !void {
+ try out_stream.writeByte('\"');
+ var i: usize = 0;
+ while (i < value.len) : (i += 1) {
+ switch (value[i]) {
+ // normal ascii character
+ 0x20...0x21, 0x23...0x2E, 0x30...0x5B, 0x5D...0x7F => |c| try out_stream.writeByte(c),
+ // only 2 characters that *must* be escaped
+ '\\' => try out_stream.writeAll("\\\\"),
+ '\"' => try out_stream.writeAll("\\\""),
+ // solidus is optional to escape
+ '/' => {
+ if (options.string.String.escape_solidus) {
+ try out_stream.writeAll("\\/");
+ } else {
+ try out_stream.writeByte('/');
+ }
+ },
+ // control characters with short escapes
+ // TODO: option to switch between unicode and 'short' forms?
+ 0x8 => try out_stream.writeAll("\\b"),
+ 0xC => try out_stream.writeAll("\\f"),
+ '\n' => try out_stream.writeAll("\\n"),
+ '\r' => try out_stream.writeAll("\\r"),
+ '\t' => try out_stream.writeAll("\\t"),
+ else => {
+ const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;
+ // control characters (only things left with 1 byte length) should always be printed as unicode escapes
+ if (ulen == 1 or options.string.String.escape_unicode) {
+ const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;
+ try outputUnicodeEscape(codepoint, out_stream);
+ } else {
+ try out_stream.writeAll(value[i .. i + ulen]);
+ }
+ i += ulen - 1;
+ },
+ }
+ }
+ try out_stream.writeByte('\"');
+}
+
pub fn stringify(
value: anytype,
options: StringifyOptions,
@@ -3048,7 +3089,7 @@ pub fn stringify(
try out_stream.writeByte('\n');
try child_whitespace.outputIndent(out_stream);
}
- try stringify(Field.name, options, out_stream);
+ try outputJsonString(Field.name, options, out_stream);
try out_stream.writeByte(':');
if (child_options.whitespace) |child_whitespace| {
if (child_whitespace.separator) {
@@ -3082,44 +3123,7 @@ pub fn stringify(
// TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
.Slice => {
if (ptr_info.child == u8 and options.string == .String and std.unicode.utf8ValidateSlice(value)) {
- try out_stream.writeByte('\"');
- var i: usize = 0;
- while (i < value.len) : (i += 1) {
- switch (value[i]) {
- // normal ascii character
- 0x20...0x21, 0x23...0x2E, 0x30...0x5B, 0x5D...0x7F => |c| try out_stream.writeByte(c),
- // only 2 characters that *must* be escaped
- '\\' => try out_stream.writeAll("\\\\"),
- '\"' => try out_stream.writeAll("\\\""),
- // solidus is optional to escape
- '/' => {
- if (options.string.String.escape_solidus) {
- try out_stream.writeAll("\\/");
- } else {
- try out_stream.writeByte('/');
- }
- },
- // control characters with short escapes
- // TODO: option to switch between unicode and 'short' forms?
- 0x8 => try out_stream.writeAll("\\b"),
- 0xC => try out_stream.writeAll("\\f"),
- '\n' => try out_stream.writeAll("\\n"),
- '\r' => try out_stream.writeAll("\\r"),
- '\t' => try out_stream.writeAll("\\t"),
- else => {
- const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;
- // control characters (only things left with 1 byte length) should always be printed as unicode escapes
- if (ulen == 1 or options.string.String.escape_unicode) {
- const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;
- try outputUnicodeEscape(codepoint, out_stream);
- } else {
- try out_stream.writeAll(value[i .. i + ulen]);
- }
- i += ulen - 1;
- },
- }
- }
- try out_stream.writeByte('\"');
+ try outputJsonString(value, options, out_stream);
return;
}