Source
pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) ParseError(@TypeOf(source.*))!@This() {
// The grammar of the stack is:
// (.array | .object .string)*
var stack = Array.init(allocator);
defer stack.deinit();
while (true) {
// Assert the stack grammar at the top of the stack.
debug.assert(stack.items.len == 0 or
stack.items[stack.items.len - 1] == .array or
(stack.items[stack.items.len - 2] == .object and stack.items[stack.items.len - 1] == .string));
switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) {
.allocated_string => |s| {
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,
.true => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = true }, options) orelse continue,
.false => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = false }, options) orelse continue,
.object_begin => {
switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) {
.object_end => return try handleCompleteValue(&stack, allocator, source, Value{ .object = ObjectMap.init(allocator) }, options) orelse continue,
.allocated_string => |key| {
try stack.appendSlice(&[_]Value{
Value{ .object = ObjectMap.init(allocator) },
Value{ .string = key },
});
},
else => unreachable,
}
},
.array_begin => {
try stack.append(Value{ .array = Array.init(allocator) });
},
.array_end => return try handleCompleteValue(&stack, allocator, source, stack.pop().?, options) orelse continue,
else => unreachable,
}
}
}