aboutsummaryrefslogtreecommitdiff
path: root/lib/std/json.zig
diff options
context:
space:
mode:
authorJanne Hellsten <jjhellst@gmail.com>2023-04-26 00:52:17 +0300
committerGitHub <noreply@github.com>2023-04-26 00:52:17 +0300
commit61236c2aa1610e0ce470bd64ba930a6430ad6de2 (patch)
treeb953ea0fe35a0c78f8e21f90ee5e542eb6040d2f /lib/std/json.zig
parent5b9e528bc550e7ea9e286fdd2324316f9895d5da (diff)
downloadzig-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.zig72
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) {