authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-05-18 02:51:02+10:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-24 20:35:47+00:00
log978a38ee40e13c3eed625f2df7b36be49fd049e0
tree60596022f326a9f62e07618863ae6f3b668739aa
parentd3ebd428650748e60db70dd2171cc044855814b1

std: fix json parsing into unions


1 files changed, 12 insertions(+), 1 deletions(-)

lib/std/json.zig+12-1
...@@ -1418,7 +1418,10 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:...@@ -1418,7 +1418,10 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:
1418 if (unionInfo.tag_type) |_| {1418 if (unionInfo.tag_type) |_| {
1419 // try each of the union fields until we find one that matches1419 // try each of the union fields until we find one that matches
1420 inline for (unionInfo.fields) |u_field| {1420 inline for (unionInfo.fields) |u_field| {
1421 if (parseInternal(u_field.field_type, token, tokens, options)) |value| {1421 // take a copy of tokens so we can withhold mutations until success
1422 var tokens_copy = tokens.*;
1423 if (parseInternal(u_field.field_type, token, &tokens_copy, options)) |value| {
1424 tokens.* = tokens_copy;
1422 return @unionInit(T, u_field.name, value);1425 return @unionInit(T, u_field.name, value);
1423 } else |err| {1426 } else |err| {
1424 // Bubble up error.OutOfMemory1427 // Bubble up error.OutOfMemory
...@@ -1733,6 +1736,14 @@ test "parse into tagged union" {...@@ -1733,6 +1736,14 @@ test "parse into tagged union" {
1733 };1736 };
1734 testing.expectEqual(T{ .x = 42 }, try parse(T, &TokenStream.init("42"), ParseOptions{}));1737 testing.expectEqual(T{ .x = 42 }, try parse(T, &TokenStream.init("42"), ParseOptions{}));
1735 }1738 }
1739
1740 { // needs to back out when first union member doesn't match
1741 const T = union(enum) {
1742 A: struct { x: u32 },
1743 B: struct { y: u32 },
1744 };
1745 testing.expectEqual(T{ .B = .{.y = 42} }, try parse(T, &TokenStream.init("{\"y\":42}"), ParseOptions{}));
1746 }
1736}1747}
17371748
1738test "parseFree descends into tagged union" {1749test "parseFree descends into tagged union" {