Last active
December 28, 2024 08:25
-
-
Save nickelca/bd4b636e9d0d9b99111fe1960dd5465e to your computer and use it in GitHub Desktop.
Parse json string into std.StringHashMap using std.json.parseFromSliceLeaky.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub fn main() !void { | |
var arena_state: std.heap.ArenaAllocator = .init(std.heap.page_allocator); | |
defer arena_state.deinit(); | |
const arena = arena_state.allocator(); | |
const parsed = try std.json.parseFromSliceLeaky(Meow, arena, | |
\\{ | |
\\ "name": "My name", | |
\\ "map": { | |
\\ "a": 1, | |
\\ "b": 2, | |
\\ "c": 3 | |
\\ } | |
\\} | |
, .{}); | |
_ = parsed; | |
} | |
const Meow = struct { | |
name: []const u8, | |
map: std.StringHashMap(u64), | |
pub fn jsonParse( | |
ally: std.mem.Allocator, | |
tokens: anytype, | |
opts: std.json.ParseOptions, | |
) std.json.ParseError(@TypeOf(tokens.*))!Meow { | |
if (try tokens.next() != .object_begin) { | |
return error.UnexpectedToken; | |
} | |
var name_opt: ?[]const u8 = null; | |
var map_opt: ?std.StringHashMap(u64) = null; | |
errdefer if (map_opt) |*map| map.deinit(); | |
while (try tokens.peekNextTokenType() == .string) { | |
const key = try tokens.nextAllocMax(ally, .alloc_if_needed, opts.max_value_len.?); | |
if (std.mem.eql(u8, key.string, "name")) { | |
if (name_opt != null) switch (opts.duplicate_field_behavior) { | |
.use_last => {}, | |
.use_first => continue, | |
.@"error" => return error.DuplicateField, | |
}; | |
name_opt = try std.json.innerParse([]const u8, ally, tokens, opts); | |
} else if (std.mem.eql(u8, key.string, "map")) { | |
if (map_opt != null) switch (opts.duplicate_field_behavior) { | |
.use_last => {}, | |
.use_first => continue, | |
.@"error" => return error.DuplicateField, | |
}; | |
map_opt = .init(ally); | |
if (try tokens.next() != .object_begin) { | |
return error.UnexpectedToken; | |
} | |
while (try tokens.peekNextTokenType() == .string) { | |
const k = try std.json.innerParse([]const u8, ally, tokens, opts); | |
const v = try std.json.innerParse(u64, ally, tokens, opts); | |
try map_opt.?.put(k, v); | |
} | |
if (try tokens.next() != .object_end) { | |
return error.UnexpectedToken; | |
} | |
} else if (!opts.ignore_unknown_fields) { | |
return error.UnknownField; | |
} | |
} | |
if (try tokens.next() != .object_end) { | |
return error.UnexpectedToken; | |
} | |
if (name_opt == null or map_opt == null) { | |
return error.MissingField; | |
} | |
return .{ | |
.name = name_opt.?, | |
.map = map_opt.?, | |
}; | |
} | |
}; | |
const std = @import("std"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment