mirror of
https://github.com/ziglang/zig.git
synced 2025-12-30 18:13:19 +00:00
Merge pull request #11618 from arBmind/json-stringify-patch
JSON stringify string setting affects keys
This commit is contained in:
commit
090461a695
@ -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;
|
||||
}
|
||||
|
||||
@ -3268,6 +3272,11 @@ test "stringify struct" {
|
||||
}{ .foo = 42 }, StringifyOptions{});
|
||||
}
|
||||
|
||||
test "stringify struct with string as array" {
|
||||
try teststringify("{\"foo\":\"bar\"}", .{ .foo = "bar" }, StringifyOptions{});
|
||||
try teststringify("{\"foo\":[98,97,114]}", .{ .foo = "bar" }, StringifyOptions{ .string = .Array });
|
||||
}
|
||||
|
||||
test "stringify struct with indentation" {
|
||||
try teststringify(
|
||||
\\{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user