authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-02-25 20:58:46+11:00
committergravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-04-01 00:12:59+11:00
log62fbb6b87406d8dd0b256ca42246b86972cd2faf
tree2c5955bfaf089c41760271588111c68fb9309dfc
parentedf487b12645ced9e0745deb32b47c594f1f3072
signaturelock-open Commit is signed but in an unrecognized format.

std: allow picking between serialising []u8 as string or array


1 files changed, 27 insertions(+), 18 deletions(-)

lib/std/json.zig+27-18
......@@ -2357,13 +2357,22 @@ pub const StringifyOptions = struct {
23572357 /// Controls the whitespace emitted
23582358 whitespace: ?Whitespace = null,
23592359
2360 /// Should '/' be escaped in strings?
2361 escape_solidus: bool = false,
2360 /// Should []u8 be serialised as a string? or an array?
2361 pub const StringOptions = union(enum) {
2362 Array,
23622363
2363 /// Should unicode characters be escaped in strings?
2364 escape_unicode: bool = false,
2364 /// String output options
2365 const StringOutputOptions = struct {
2366 /// Should '/' be escaped in strings?
2367 escape_solidus: bool = false,
23652368
2366 // TODO: allow picking if []u8 is string or array?
2369 /// Should unicode characters be escaped in strings?
2370 escape_unicode: bool = false,
2371 };
2372 String: StringOutputOptions,
2373 };
2374
2375 string: StringOptions = StringOptions{ .String = .{} },
23672376};
23682377
23692378fn outputUnicodeEscape(
......@@ -2490,7 +2499,7 @@ pub fn stringify(
24902499 },
24912500 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
24922501 .Slice => {
2493 if (ptr_info.child == u8 and std.unicode.utf8ValidateSlice(value)) {
2502 if (ptr_info.child == u8 and options.string == .String and std.unicode.utf8ValidateSlice(value)) {
24942503 try out_stream.writeByte('\"');
24952504 var i: usize = 0;
24962505 while (i < value.len) : (i += 1) {
......@@ -2502,7 +2511,7 @@ pub fn stringify(
25022511 '\"' => try out_stream.writeAll("\\\""),
25032512 // solidus is optional to escape
25042513 '/' => {
2505 if (options.escape_solidus) {
2514 if (options.string.String.escape_solidus) {
25062515 try out_stream.writeAll("\\/");
25072516 } else {
25082517 try out_stream.writeByte('\\');
......@@ -2518,7 +2527,7 @@ pub fn stringify(
25182527 else => {
25192528 const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;
25202529 // control characters (only things left with 1 byte length) should always be printed as unicode escapes
2521 if (ulen == 1 or options.escape_unicode) {
2530 if (ulen == 1 or options.string.String.escape_unicode) {
25222531 const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;
25232532 try outputUnicodeEscape(codepoint, out_stream);
25242533 } else {
......@@ -2636,25 +2645,25 @@ test "stringify basic types" {
26362645test "stringify string" {
26372646 try teststringify("\"hello\"", "hello", StringifyOptions{});
26382647 try teststringify("\"with\\nescapes\\r\"", "with\nescapes\r", StringifyOptions{});
2639 try teststringify("\"with\\nescapes\\r\"", "with\nescapes\r", StringifyOptions{ .escape_unicode = true });
2648 try teststringify("\"with\\nescapes\\r\"", "with\nescapes\r", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26402649 try teststringify("\"with unicode\\u0001\"", "with unicode\u{1}", StringifyOptions{});
2641 try teststringify("\"with unicode\\u0001\"", "with unicode\u{1}", StringifyOptions{ .escape_unicode = true });
2650 try teststringify("\"with unicode\\u0001\"", "with unicode\u{1}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26422651 try teststringify("\"with unicode\u{80}\"", "with unicode\u{80}", StringifyOptions{});
2643 try teststringify("\"with unicode\\u0080\"", "with unicode\u{80}", StringifyOptions{ .escape_unicode = true });
2652 try teststringify("\"with unicode\\u0080\"", "with unicode\u{80}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26442653 try teststringify("\"with unicode\u{FF}\"", "with unicode\u{FF}", StringifyOptions{});
2645 try teststringify("\"with unicode\\u00ff\"", "with unicode\u{FF}", StringifyOptions{ .escape_unicode = true });
2654 try teststringify("\"with unicode\\u00ff\"", "with unicode\u{FF}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26462655 try teststringify("\"with unicode\u{100}\"", "with unicode\u{100}", StringifyOptions{});
2647 try teststringify("\"with unicode\\u0100\"", "with unicode\u{100}", StringifyOptions{ .escape_unicode = true });
2656 try teststringify("\"with unicode\\u0100\"", "with unicode\u{100}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26482657 try teststringify("\"with unicode\u{800}\"", "with unicode\u{800}", StringifyOptions{});
2649 try teststringify("\"with unicode\\u0800\"", "with unicode\u{800}", StringifyOptions{ .escape_unicode = true });
2658 try teststringify("\"with unicode\\u0800\"", "with unicode\u{800}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26502659 try teststringify("\"with unicode\u{8000}\"", "with unicode\u{8000}", StringifyOptions{});
2651 try teststringify("\"with unicode\\u8000\"", "with unicode\u{8000}", StringifyOptions{ .escape_unicode = true });
2660 try teststringify("\"with unicode\\u8000\"", "with unicode\u{8000}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26522661 try teststringify("\"with unicode\u{D799}\"", "with unicode\u{D799}", StringifyOptions{});
2653 try teststringify("\"with unicode\\ud799\"", "with unicode\u{D799}", StringifyOptions{ .escape_unicode = true });
2662 try teststringify("\"with unicode\\ud799\"", "with unicode\u{D799}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26542663 try teststringify("\"with unicode\u{10000}\"", "with unicode\u{10000}", StringifyOptions{});
2655 try teststringify("\"with unicode\\ud800\\udc00\"", "with unicode\u{10000}", StringifyOptions{ .escape_unicode = true });
2664 try teststringify("\"with unicode\\ud800\\udc00\"", "with unicode\u{10000}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26562665 try teststringify("\"with unicode\u{10FFFF}\"", "with unicode\u{10FFFF}", StringifyOptions{});
2657 try teststringify("\"with unicode\\udbff\\udfff\"", "with unicode\u{10FFFF}", StringifyOptions{ .escape_unicode = true });
2666 try teststringify("\"with unicode\\udbff\\udfff\"", "with unicode\u{10FFFF}", StringifyOptions{ .string = .{ .String = .{ .escape_unicode = true } } });
26582667}
26592668
26602669test "stringify tagged unions" {