| ... | @@ -1389,6 +1389,11 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ | ... | @@ -1389,6 +1389,11 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ |
| 1389 | UnescapeValidStringError || | 1389 | UnescapeValidStringError || |
| 1390 | ParseInternalErrorImpl(arrayInfo.child, inferred_types ++ [_]type{T}); | 1390 | ParseInternalErrorImpl(arrayInfo.child, inferred_types ++ [_]type{T}); |
| 1391 | }, | 1391 | }, |
| | 1392 | .Vector => |vecInfo| { |
| | 1393 | return error{ UnexpectedEndOfJson, UnexpectedToken, LengthMismatch } || TokenStream.Error || |
| | 1394 | UnescapeValidStringError || |
| | 1395 | ParseInternalErrorImpl(vecInfo.child, inferred_types ++ [_]type{T}); |
| | 1396 | }, |
| 1392 | .Pointer => |ptrInfo| { | 1397 | .Pointer => |ptrInfo| { |
| 1393 | var errors = error{AllocatorRequired} || std.mem.Allocator.Error; | 1398 | var errors = error{AllocatorRequired} || std.mem.Allocator.Error; |
| 1394 | switch (ptrInfo.size) { | 1399 | switch (ptrInfo.size) { |
| ... | @@ -1408,6 +1413,35 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ | ... | @@ -1408,6 +1413,35 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ |
| 1408 | unreachable; | 1413 | unreachable; |
| 1409 | } | 1414 | } |
| 1410 | | 1415 | |
| | 1416 | fn parseInternalArray( |
| | 1417 | comptime T: type, |
| | 1418 | comptime Elt: type, |
| | 1419 | comptime arr_len: usize, |
| | 1420 | tokens: *TokenStream, |
| | 1421 | options: ParseOptions, |
| | 1422 | ) ParseInternalError(T)!T { |
| | 1423 | var r: T = undefined; |
| | 1424 | var i: usize = 0; |
| | 1425 | var child_options = options; |
| | 1426 | child_options.allow_trailing_data = true; |
| | 1427 | errdefer { |
| | 1428 | // Without the r.len check `r[i]` is not allowed |
| | 1429 | if (arr_len > 0) while (true) : (i -= 1) { |
| | 1430 | parseFree(Elt, r[i], options); |
| | 1431 | if (i == 0) break; |
| | 1432 | }; |
| | 1433 | } |
| | 1434 | if (arr_len > 0) while (i < arr_len) : (i += 1) { |
| | 1435 | r[i] = try parse(Elt, tokens, child_options); |
| | 1436 | }; |
| | 1437 | const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson; |
| | 1438 | switch (tok) { |
| | 1439 | .ArrayEnd => {}, |
| | 1440 | else => return error.UnexpectedToken, |
| | 1441 | } |
| | 1442 | return r; |
| | 1443 | } |
| | 1444 | |
| 1411 | fn parseInternal( | 1445 | fn parseInternal( |
| 1412 | comptime T: type, | 1446 | comptime T: type, |
| 1413 | token: Token, | 1447 | token: Token, |
| ... | @@ -1624,26 +1658,8 @@ fn parseInternal( | ... | @@ -1624,26 +1658,8 @@ fn parseInternal( |
| 1624 | .Array => |arrayInfo| { | 1658 | .Array => |arrayInfo| { |
| 1625 | switch (token) { | 1659 | switch (token) { |
| 1626 | .ArrayBegin => { | 1660 | .ArrayBegin => { |
| 1627 | var r: T = undefined; | 1661 | const len = @typeInfo(T).Array.len; |
| 1628 | var i: usize = 0; | 1662 | return parseInternalArray(T, arrayInfo.child, len, tokens, options); |
| 1629 | var child_options = options; | | |
| 1630 | child_options.allow_trailing_data = true; | | |
| 1631 | errdefer { | | |
| 1632 | // Without the r.len check `r[i]` is not allowed | | |
| 1633 | if (r.len > 0) while (true) : (i -= 1) { | | |
| 1634 | parseFree(arrayInfo.child, r[i], options); | | |
| 1635 | if (i == 0) break; | | |
| 1636 | }; | | |
| 1637 | } | | |
| 1638 | while (i < r.len) : (i += 1) { | | |
| 1639 | r[i] = try parse(arrayInfo.child, tokens, child_options); | | |
| 1640 | } | | |
| 1641 | const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson; | | |
| 1642 | switch (tok) { | | |
| 1643 | .ArrayEnd => {}, | | |
| 1644 | else => return error.UnexpectedToken, | | |
| 1645 | } | | |
| 1646 | return r; | | |
| 1647 | }, | 1663 | }, |
| 1648 | .String => |stringToken| { | 1664 | .String => |stringToken| { |
| 1649 | if (arrayInfo.child != u8) return error.UnexpectedToken; | 1665 | if (arrayInfo.child != u8) return error.UnexpectedToken; |
| ... | @@ -1659,6 +1675,15 @@ fn parseInternal( | ... | @@ -1659,6 +1675,15 @@ fn parseInternal( |
| 1659 | else => return error.UnexpectedToken, | 1675 | else => return error.UnexpectedToken, |
| 1660 | } | 1676 | } |
| 1661 | }, | 1677 | }, |
| | 1678 | .Vector => |vecInfo| { |
| | 1679 | switch (token) { |
| | 1680 | .ArrayBegin => { |
| | 1681 | const len = @typeInfo(T).Vector.len; |
| | 1682 | return parseInternalArray(T, vecInfo.child, len, tokens, options); |
| | 1683 | }, |
| | 1684 | else => return error.UnexpectedToken, |
| | 1685 | } |
| | 1686 | }, |
| 1662 | .Pointer => |ptrInfo| { | 1687 | .Pointer => |ptrInfo| { |
| 1663 | const allocator = options.allocator orelse return error.AllocatorRequired; | 1688 | const allocator = options.allocator orelse return error.AllocatorRequired; |
| 1664 | switch (ptrInfo.size) { | 1689 | switch (ptrInfo.size) { |
| ... | @@ -1804,6 +1829,13 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void { | ... | @@ -1804,6 +1829,13 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void { |
| 1804 | parseFree(arrayInfo.child, v, options); | 1829 | parseFree(arrayInfo.child, v, options); |
| 1805 | } | 1830 | } |
| 1806 | }, | 1831 | }, |
| | 1832 | .Vector => |vecInfo| { |
| | 1833 | var i: usize = 0; |
| | 1834 | var v_len: usize = @typeInfo(@TypeOf(value)).Vector.len; |
| | 1835 | while (i < v_len) : (i += 1) { |
| | 1836 | parseFree(vecInfo.child, value[i], options); |
| | 1837 | } |
| | 1838 | }, |
| 1807 | .Pointer => |ptrInfo| { | 1839 | .Pointer => |ptrInfo| { |
| 1808 | const allocator = options.allocator orelse unreachable; | 1840 | const allocator = options.allocator orelse unreachable; |
| 1809 | switch (ptrInfo.size) { | 1841 | switch (ptrInfo.size) { |