authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2021-01-28 19:15:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-01 12:40:49-08:00
log06b29c854656a1f9320ee16024b1c3a6b78180a5
treee26cc2f2abdc8215f5699ccfd030709f38da84fa
parent1032a693211dd96abe349bfa76b43bb1f226cfda

std.json large number support


1 files changed, 20 insertions(+), 3 deletions(-)

lib/std/json.zig+20-3
...@@ -1255,6 +1255,7 @@ pub const Value = union(enum) {...@@ -1255,6 +1255,7 @@ pub const Value = union(enum) {
1255 Bool: bool,1255 Bool: bool,
1256 Integer: i64,1256 Integer: i64,
1257 Float: f64,1257 Float: f64,
1258 NumberString: []const u8,
1258 String: []const u8,1259 String: []const u8,
1259 Array: Array,1260 Array: Array,
1260 Object: ObjectMap,1261 Object: ObjectMap,
...@@ -1269,6 +1270,7 @@ pub const Value = union(enum) {...@@ -1269,6 +1270,7 @@ pub const Value = union(enum) {
1269 .Bool => |inner| try stringify(inner, options, out_stream),1270 .Bool => |inner| try stringify(inner, options, out_stream),
1270 .Integer => |inner| try stringify(inner, options, out_stream),1271 .Integer => |inner| try stringify(inner, options, out_stream),
1271 .Float => |inner| try stringify(inner, options, out_stream),1272 .Float => |inner| try stringify(inner, options, out_stream),
1273 .NumberString => |inner| try out_stream.writeAll(inner),
1272 .String => |inner| try stringify(inner, options, out_stream),1274 .String => |inner| try stringify(inner, options, out_stream),
1273 .Array => |inner| try stringify(inner.items, options, out_stream),1275 .Array => |inner| try stringify(inner.items, options, out_stream),
1274 .Object => |inner| {1276 .Object => |inner| {
...@@ -1338,6 +1340,12 @@ test "Value.jsonStringify" {...@@ -1338,6 +1340,12 @@ test "Value.jsonStringify" {
1338 try (Value{ .Integer = 42 }).jsonStringify(.{}, fbs.writer());1340 try (Value{ .Integer = 42 }).jsonStringify(.{}, fbs.writer());
1339 testing.expectEqualSlices(u8, fbs.getWritten(), "42");1341 testing.expectEqualSlices(u8, fbs.getWritten(), "42");
1340 }1342 }
1343 {
1344 var buffer: [10]u8 = undefined;
1345 var fbs = std.io.fixedBufferStream(&buffer);
1346 try (Value{ .NumberString = "43" }).jsonStringify(.{}, fbs.writer());
1347 testing.expectEqualSlices(u8, fbs.getWritten(), "43");
1348 }
1341 {1349 {
1342 var buffer: [10]u8 = undefined;1350 var buffer: [10]u8 = undefined;
1343 var fbs = std.io.fixedBufferStream(&buffer);1351 var fbs = std.io.fixedBufferStream(&buffer);
...@@ -1356,7 +1364,7 @@ test "Value.jsonStringify" {...@@ -1356,7 +1364,7 @@ test "Value.jsonStringify" {
1356 var vals = [_]Value{1364 var vals = [_]Value{
1357 .{ .Integer = 1 },1365 .{ .Integer = 1 },
1358 .{ .Integer = 2 },1366 .{ .Integer = 2 },
1359 .{ .Integer = 3 },1367 .{ .NumberString = "3" },
1360 };1368 };
1361 try (Value{1369 try (Value{
1362 .Array = Array.fromOwnedSlice(undefined, &vals),1370 .Array = Array.fromOwnedSlice(undefined, &vals),
...@@ -2205,7 +2213,12 @@ pub const Parser = struct {...@@ -2205,7 +2213,12 @@ pub const Parser = struct {
22052213
2206 fn parseNumber(p: *Parser, n: std.meta.TagPayload(Token, Token.Number), input: []const u8, i: usize) !Value {2214 fn parseNumber(p: *Parser, n: std.meta.TagPayload(Token, Token.Number), input: []const u8, i: usize) !Value {
2207 return if (n.is_integer)2215 return if (n.is_integer)
2208 Value{ .Integer = try std.fmt.parseInt(i64, n.slice(input, i), 10) }2216 Value{
2217 .Integer = std.fmt.parseInt(i64, n.slice(input, i), 10) catch |e| switch (e) {
2218 error.Overflow => return Value{ .NumberString = n.slice(input, i) },
2219 error.InvalidCharacter => |err| return err,
2220 },
2221 }
2209 else2222 else
2210 Value{ .Float = try std.fmt.parseFloat(f64, n.slice(input, i)) };2223 Value{ .Float = try std.fmt.parseFloat(f64, n.slice(input, i)) };
2211 }2224 }
...@@ -2293,7 +2306,8 @@ test "json.parser.dynamic" {...@@ -2293,7 +2306,8 @@ test "json.parser.dynamic" {
2293 \\ "Animated" : false,2306 \\ "Animated" : false,
2294 \\ "IDs": [116, 943, 234, 38793],2307 \\ "IDs": [116, 943, 234, 38793],
2295 \\ "ArrayOfObject": [{"n": "m"}],2308 \\ "ArrayOfObject": [{"n": "m"}],
2296 \\ "double": 1.34122309 \\ "double": 1.3412,
2310 \\ "LargeInt": 18446744073709551615
2297 \\ }2311 \\ }
2298 \\}2312 \\}
2299 ;2313 ;
...@@ -2325,6 +2339,9 @@ test "json.parser.dynamic" {...@@ -2325,6 +2339,9 @@ test "json.parser.dynamic" {
23252339
2326 const double = image.Object.get("double").?;2340 const double = image.Object.get("double").?;
2327 testing.expect(double.Float == 1.3412);2341 testing.expect(double.Float == 1.3412);
2342
2343 const large_int = image.Object.get("LargeInt").?;
2344 testing.expect(mem.eql(u8, large_int.NumberString, "18446744073709551615"));
2328}2345}
23292346
2330test "import more json tests" {2347test "import more json tests" {