diff options
| author | Janne Hellsten <jjhellst@gmail.com> | 2023-04-26 00:52:17 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-26 00:52:17 +0300 |
| commit | 61236c2aa1610e0ce470bd64ba930a6430ad6de2 (patch) | |
| tree | b953ea0fe35a0c78f8e21f90ee5e542eb6040d2f /lib/std/json.zig | |
| parent | 5b9e528bc550e7ea9e286fdd2324316f9895d5da (diff) | |
| download | zig-61236c2aa1610e0ce470bd64ba930a6430ad6de2.tar.gz zig-61236c2aa1610e0ce470bd64ba930a6430ad6de2.zip | |
std: @Vector support for std.json.parse
Diffstat (limited to 'lib/std/json.zig')
| -rw-r--r-- | lib/std/json.zig | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/lib/std/json.zig b/lib/std/json.zig index 096bed8d06..ca7fb5ad20 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1389,6 +1389,11 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ UnescapeValidStringError || ParseInternalErrorImpl(arrayInfo.child, inferred_types ++ [_]type{T}); }, + .Vector => |vecInfo| { + return error{ UnexpectedEndOfJson, UnexpectedToken, LengthMismatch } || TokenStream.Error || + UnescapeValidStringError || + ParseInternalErrorImpl(vecInfo.child, inferred_types ++ [_]type{T}); + }, .Pointer => |ptrInfo| { var errors = error{AllocatorRequired} || std.mem.Allocator.Error; switch (ptrInfo.size) { @@ -1408,6 +1413,35 @@ fn ParseInternalErrorImpl(comptime T: type, comptime inferred_types: []const typ unreachable; } +fn parseInternalArray( + comptime T: type, + comptime Elt: type, + comptime arr_len: usize, + tokens: *TokenStream, + options: ParseOptions, +) ParseInternalError(T)!T { + var r: T = undefined; + var i: usize = 0; + var child_options = options; + child_options.allow_trailing_data = true; + errdefer { + // Without the r.len check `r[i]` is not allowed + if (arr_len > 0) while (true) : (i -= 1) { + parseFree(Elt, r[i], options); + if (i == 0) break; + }; + } + if (arr_len > 0) while (i < arr_len) : (i += 1) { + r[i] = try parse(Elt, tokens, child_options); + }; + const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson; + switch (tok) { + .ArrayEnd => {}, + else => return error.UnexpectedToken, + } + return r; +} + fn parseInternal( comptime T: type, token: Token, @@ -1624,26 +1658,8 @@ fn parseInternal( .Array => |arrayInfo| { switch (token) { .ArrayBegin => { - var r: T = undefined; - var i: usize = 0; - var child_options = options; - child_options.allow_trailing_data = true; - errdefer { - // Without the r.len check `r[i]` is not allowed - if (r.len > 0) while (true) : (i -= 1) { - parseFree(arrayInfo.child, r[i], options); - if (i == 0) break; - }; - } - while (i < r.len) : (i += 1) { - r[i] = try parse(arrayInfo.child, tokens, child_options); - } - const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson; - switch (tok) { - .ArrayEnd => {}, - else => return error.UnexpectedToken, - } - return r; + const len = @typeInfo(T).Array.len; + return parseInternalArray(T, arrayInfo.child, len, tokens, options); }, .String => |stringToken| { if (arrayInfo.child != u8) return error.UnexpectedToken; @@ -1659,6 +1675,15 @@ fn parseInternal( else => return error.UnexpectedToken, } }, + .Vector => |vecInfo| { + switch (token) { + .ArrayBegin => { + const len = @typeInfo(T).Vector.len; + return parseInternalArray(T, vecInfo.child, len, tokens, options); + }, + else => return error.UnexpectedToken, + } + }, .Pointer => |ptrInfo| { const allocator = options.allocator orelse return error.AllocatorRequired; switch (ptrInfo.size) { @@ -1804,6 +1829,13 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void { parseFree(arrayInfo.child, v, options); } }, + .Vector => |vecInfo| { + var i: usize = 0; + var v_len: usize = @typeInfo(@TypeOf(value)).Vector.len; + while (i < v_len) : (i += 1) { + parseFree(vecInfo.child, value[i], options); + } + }, .Pointer => |ptrInfo| { const allocator = options.allocator orelse unreachable; switch (ptrInfo.size) { |
