| ... | @@ -1511,6 +1511,34 @@ fn parseInternal( | ... | @@ -1511,6 +1511,34 @@ fn parseInternal( |
| 1511 | } | 1511 | } |
| 1512 | }, | 1512 | }, |
| 1513 | .Struct => |structInfo| { | 1513 | .Struct => |structInfo| { |
| | 1514 | if (structInfo.is_tuple) { |
| | 1515 | switch (token) { |
| | 1516 | .ArrayBegin => {}, |
| | 1517 | else => return error.UnexpectedToken, |
| | 1518 | } |
| | 1519 | var r: T = undefined; |
| | 1520 | var child_options = options; |
| | 1521 | child_options.allow_trailing_data = true; |
| | 1522 | var fields_seen: usize = 0; |
| | 1523 | errdefer { |
| | 1524 | inline for (0..structInfo.fields.len) |i| { |
| | 1525 | if (i < fields_seen) { |
| | 1526 | parseFree(structInfo.fields[i].type, r[i], options); |
| | 1527 | } |
| | 1528 | } |
| | 1529 | } |
| | 1530 | inline for (0..structInfo.fields.len) |i| { |
| | 1531 | r[i] = try parse(structInfo.fields[i].type, tokens, child_options); |
| | 1532 | fields_seen = i + 1; |
| | 1533 | } |
| | 1534 | const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson; |
| | 1535 | switch (tok) { |
| | 1536 | .ArrayEnd => {}, |
| | 1537 | else => return error.UnexpectedToken, |
| | 1538 | } |
| | 1539 | return r; |
| | 1540 | } |
| | 1541 | |
| 1514 | switch (token) { | 1542 | switch (token) { |
| 1515 | .ObjectBegin => {}, | 1543 | .ObjectBegin => {}, |
| 1516 | else => return error.UnexpectedToken, | 1544 | else => return error.UnexpectedToken, |
| ... | @@ -2290,7 +2318,7 @@ pub fn stringify( | ... | @@ -2290,7 +2318,7 @@ pub fn stringify( |
| 2290 | return value.jsonStringify(options, out_stream); | 2318 | return value.jsonStringify(options, out_stream); |
| 2291 | } | 2319 | } |
| 2292 | | 2320 | |
| 2293 | try out_stream.writeByte('{'); | 2321 | try out_stream.writeByte(if (S.is_tuple) '[' else '{'); |
| 2294 | var field_output = false; | 2322 | var field_output = false; |
| 2295 | var child_options = options; | 2323 | var child_options = options; |
| 2296 | if (child_options.whitespace) |*child_whitespace| { | 2324 | if (child_options.whitespace) |*child_whitespace| { |
| ... | @@ -2320,11 +2348,13 @@ pub fn stringify( | ... | @@ -2320,11 +2348,13 @@ pub fn stringify( |
| 2320 | if (child_options.whitespace) |child_whitespace| { | 2348 | if (child_options.whitespace) |child_whitespace| { |
| 2321 | try child_whitespace.outputIndent(out_stream); | 2349 | try child_whitespace.outputIndent(out_stream); |
| 2322 | } | 2350 | } |
| 2323 | try encodeJsonString(Field.name, options, out_stream); | 2351 | if (!S.is_tuple) { |
| 2324 | try out_stream.writeByte(':'); | 2352 | try encodeJsonString(Field.name, options, out_stream); |
| 2325 | if (child_options.whitespace) |child_whitespace| { | 2353 | try out_stream.writeByte(':'); |
| 2326 | if (child_whitespace.separator) { | 2354 | if (child_options.whitespace) |child_whitespace| { |
| 2327 | try out_stream.writeByte(' '); | 2355 | if (child_whitespace.separator) { |
| | 2356 | try out_stream.writeByte(' '); |
| | 2357 | } |
| 2328 | } | 2358 | } |
| 2329 | } | 2359 | } |
| 2330 | try stringify(@field(value, Field.name), child_options, out_stream); | 2360 | try stringify(@field(value, Field.name), child_options, out_stream); |
| ... | @@ -2335,7 +2365,7 @@ pub fn stringify( | ... | @@ -2335,7 +2365,7 @@ pub fn stringify( |
| 2335 | try whitespace.outputIndent(out_stream); | 2365 | try whitespace.outputIndent(out_stream); |
| 2336 | } | 2366 | } |
| 2337 | } | 2367 | } |
| 2338 | try out_stream.writeByte('}'); | 2368 | try out_stream.writeByte(if (S.is_tuple) ']' else '}'); |
| 2339 | return; | 2369 | return; |
| 2340 | }, | 2370 | }, |
| 2341 | .ErrorSet => return stringify(@as([]const u8, @errorName(value)), options, out_stream), | 2371 | .ErrorSet => return stringify(@as([]const u8, @errorName(value)), options, out_stream), |
| ... | @@ -2649,6 +2679,10 @@ test "stringify vector" { | ... | @@ -2649,6 +2679,10 @@ test "stringify vector" { |
| 2649 | try teststringify("[1,1]", @splat(2, @as(u32, 1)), StringifyOptions{}); | 2679 | try teststringify("[1,1]", @splat(2, @as(u32, 1)), StringifyOptions{}); |
| 2650 | } | 2680 | } |
| 2651 | | 2681 | |
| | 2682 | test "stringify tuple" { |
| | 2683 | try teststringify("[\"foo\",42]", std.meta.Tuple(&.{ []const u8, usize }){ "foo", 42 }, StringifyOptions{}); |
| | 2684 | } |
| | 2685 | |
| 2652 | fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions) !void { | 2686 | fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions) !void { |
| 2653 | const ValidationWriter = struct { | 2687 | const ValidationWriter = struct { |
| 2654 | const Self = @This(); | 2688 | const Self = @This(); |