mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
Add std.json.ParseOptions.parse_numbers
to preserve float precision (#20744)
This commit is contained in:
parent
ed847b85c2
commit
81a172a506
@ -22,6 +22,7 @@ pub const Array = ArrayList(Value);
|
||||
/// Represents any JSON value, potentially containing other JSON values.
|
||||
/// A .float value may be an approximation of the original value.
|
||||
/// Arbitrary precision numbers can be represented by .number_string values.
|
||||
/// See also `std.json.ParseOptions.parse_numbers`.
|
||||
pub const Value = union(enum) {
|
||||
null,
|
||||
bool: bool,
|
||||
@ -97,7 +98,11 @@ pub const Value = union(enum) {
|
||||
return try handleCompleteValue(&stack, allocator, source, Value{ .string = s }, options) orelse continue;
|
||||
},
|
||||
.allocated_number => |slice| {
|
||||
if (options.parse_numbers) {
|
||||
return try handleCompleteValue(&stack, allocator, source, Value.parseFromNumberSlice(slice), options) orelse continue;
|
||||
} else {
|
||||
return try handleCompleteValue(&stack, allocator, source, Value{ .number_string = slice }, options) orelse continue;
|
||||
}
|
||||
},
|
||||
|
||||
.null => return try handleCompleteValue(&stack, allocator, source, .null, options) orelse continue,
|
||||
|
@ -149,6 +149,19 @@ test "integer after float has proper type" {
|
||||
try std.testing.expect(parsed.object.get("ints").?.array.items[0] == .integer);
|
||||
}
|
||||
|
||||
test "ParseOptions.parse_numbers prevents parsing when false" {
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
const parsed = try parseFromSliceLeaky(Value, arena_allocator.allocator(),
|
||||
\\{
|
||||
\\ "float": 3.14,
|
||||
\\ "int": 3
|
||||
\\}
|
||||
, .{ .parse_numbers = false });
|
||||
try std.testing.expect(parsed.object.get("float").? == .number_string);
|
||||
try std.testing.expect(parsed.object.get("int").? == .number_string);
|
||||
}
|
||||
|
||||
test "escaped characters" {
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
|
@ -42,6 +42,15 @@ pub const ParseOptions = struct {
|
||||
/// The default with a `*std.json.Reader` input is `.alloc_always`.
|
||||
/// Ignored for `parseFromValue` and `parseFromValueLeaky`.
|
||||
allocate: ?AllocWhen = null,
|
||||
|
||||
/// When parsing to a `std.json.Value`, set this option to false to always emit
|
||||
/// JSON numbers as unparsed `std.json.Value.number_string`.
|
||||
/// Otherwise, JSON numbers are parsed as either `std.json.Value.integer`,
|
||||
/// `std.json.Value.float` or left as unparsed `std.json.Value.number_string`
|
||||
/// depending on the format and value of the JSON number.
|
||||
/// When this option is true, JSON numbers encoded as floats (see `std.json.isNumberFormattedLikeAnInteger`)
|
||||
/// may lose precision when being parsed into `std.json.Value.float`.
|
||||
parse_numbers: bool = true,
|
||||
};
|
||||
|
||||
pub fn Parsed(comptime T: type) type {
|
||||
|
Loading…
Reference in New Issue
Block a user