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 {...@@ -2357,13 +2357,22 @@ pub const StringifyOptions = struct {
2357 /// Controls the whitespace emitted2357 /// Controls the whitespace emitted
2358 whitespace: ?Whitespace = null,2358 whitespace: ?Whitespace = null,
23592359
2360 /// Should '/' be escaped in strings?2360 /// Should []u8 be serialised as a string? or an array?
2361 escape_solidus: bool = false,2361 pub const StringOptions = union(enum) {
2362 Array,
23622363
2363 /// Should unicode characters be escaped in strings?2364 /// String output options
2364 escape_unicode: bool = false,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 = .{} },
2367};2376};
23682377
2369fn outputUnicodeEscape(2378fn outputUnicodeEscape(
...@@ -2490,7 +2499,7 @@ pub fn stringify(...@@ -2490,7 +2499,7 @@ pub fn stringify(
2490 },2499 },
2491 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)2500 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
2492 .Slice => {2501 .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)) {
2494 try out_stream.writeByte('\"');2503 try out_stream.writeByte('\"');
2495 var i: usize = 0;2504 var i: usize = 0;
2496 while (i < value.len) : (i += 1) {2505 while (i < value.len) : (i += 1) {
...@@ -2502,7 +2511,7 @@ pub fn stringify(...@@ -2502,7 +2511,7 @@ pub fn stringify(
2502 '\"' => try out_stream.writeAll("\\\""),2511 '\"' => try out_stream.writeAll("\\\""),
2503 // solidus is optional to escape2512 // solidus is optional to escape
2504 '/' => {2513 '/' => {
2505 if (options.escape_solidus) {2514 if (options.string.String.escape_solidus) {
2506 try out_stream.writeAll("\\/");2515 try out_stream.writeAll("\\/");
2507 } else {2516 } else {
2508 try out_stream.writeByte('\\');2517 try out_stream.writeByte('\\');
...@@ -2518,7 +2527,7 @@ pub fn stringify(...@@ -2518,7 +2527,7 @@ pub fn stringify(
2518 else => {2527 else => {
2519 const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;2528 const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;
2520 // control characters (only things left with 1 byte length) should always be printed as unicode escapes2529 // 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) {
2522 const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;2531 const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;
2523 try outputUnicodeEscape(codepoint, out_stream);2532 try outputUnicodeEscape(codepoint, out_stream);
2524 } else {2533 } else {
...@@ -2636,25 +2645,25 @@ test "stringify basic types" {...@@ -2636,25 +2645,25 @@ test "stringify basic types" {
2636test "stringify string" {2645test "stringify string" {
2637 try teststringify("\"hello\"", "hello", StringifyOptions{});2646 try teststringify("\"hello\"", "hello", StringifyOptions{});
2638 try teststringify("\"with\\nescapes\\r\"", "with\nescapes\r", StringifyOptions{});2647 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 } } });
2640 try teststringify("\"with unicode\\u0001\"", "with unicode\u{1}", StringifyOptions{});2649 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 } } });
2642 try teststringify("\"with unicode\u{80}\"", "with unicode\u{80}", StringifyOptions{});2651 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 } } });
2644 try teststringify("\"with unicode\u{FF}\"", "with unicode\u{FF}", StringifyOptions{});2653 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 } } });
2646 try teststringify("\"with unicode\u{100}\"", "with unicode\u{100}", StringifyOptions{});2655 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 } } });
2648 try teststringify("\"with unicode\u{800}\"", "with unicode\u{800}", StringifyOptions{});2657 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 } } });
2650 try teststringify("\"with unicode\u{8000}\"", "with unicode\u{8000}", StringifyOptions{});2659 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 } } });
2652 try teststringify("\"with unicode\u{D799}\"", "with unicode\u{D799}", StringifyOptions{});2661 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 } } });
2654 try teststringify("\"with unicode\u{10000}\"", "with unicode\u{10000}", StringifyOptions{});2663 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 } } });
2656 try teststringify("\"with unicode\u{10FFFF}\"", "with unicode\u{10FFFF}", StringifyOptions{});2665 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 } } });
2658}2667}
26592668
2660test "stringify tagged unions" {2669test "stringify tagged unions" {