As @Sze said, the idiomatic choice here is []const []const u8
.
However, if you really need an ArrayList
, you could write a wrapper that implements jsonParse
:
Example
test "ArrayList" {
const input =
\\{"items":["item1", "item2", "item3"]}
;
const expected: []const []const u8 = &.{ "item1", "item2", "item3" };
const parsed = try std.json.parseFromSlice(DataList, std.testing.allocator, input, .{});
defer parsed.deinit();
for (0..expected.len) |i| {
try std.testing.expectEqualSlices(u8, expected[i], parsed.value.items.inner.items[i]);
}
}
const std = @import("std");
fn ArrayListJson(T: type) type {
return struct {
inner: std.ArrayList(T),
pub fn jsonParse(allocator: std.mem.Allocator, source: anytype, options: std.json.ParseOptions) !@This() {
var list = std.ArrayList(T).init(allocator);
errdefer list.deinit();
if (try source.next() != .array_begin) {
return error.UnexpectedToken;
}
while (true) {
const token = try source.nextAlloc(allocator, options.allocate.?);
switch (token) {
inline .string, .allocated_string => |s| try list.append(s),
.array_end => break,
else => {
std.debug.print("reached unreachable with token {s}\n", .{@tagName(token)});
unreachable;
},
}
}
return .{ .inner = list };
}
};
}
const DataList = struct {
items: ArrayListJson([]const u8),
};
However, I would advise against this approach.