diff --git a/src/json.zig b/src/json.zig index f29c9fd..1dbf70a 100644 --- a/src/json.zig +++ b/src/json.zig @@ -31,6 +31,12 @@ pub const Obj = struct { return Obj{ .obj = c.json_tokener_parse(s).? }; } + // Not *const Obj because the json_object retains ownership of the string + pub fn getString(self: *Obj) []const u8 { + // TODO: Check type to not allow other types + return std.mem.sliceTo(c.json_object_get_string(self.obj), 0); + } + pub fn deinit(self: *Obj) void { _ = c.json_object_put(self.obj); } @@ -54,6 +60,14 @@ pub const Obj = struct { return Obj{ .obj = c.json_object_get(obj).? }; } + pub fn objectGetIterator(self: *Obj) ObjectIterator { + // TODO: Check errors + return ObjectIterator{ + .it = c.json_object_iter_begin(self.obj), + .end = c.json_object_iter_end(self.obj), + }; + } + pub fn objectAdd(self: *Obj, key: [*c]const u8, value: ?*Obj) void { // TODO: Check type and error return @@ -63,6 +77,38 @@ pub const Obj = struct { _ = c.json_object_object_add(self.obj, key, o); } + pub const ObjectIterator = struct { + it: c.json_object_iterator, + end: c.json_object_iterator, + + const ReturnType = struct { + key: []const u8, + value: ?Obj, + }; + + // These function's names are way too long ._. + const step = c.json_object_iter_next; + const equal = c.json_object_iter_equal; + const peekName = c.json_object_iter_peek_name; + const peekValue = c.json_object_iter_peek_value; + + /// Step the iterator. The owner mustn't call deinit() on the returned value. + pub fn next(self: *ObjectIterator) ?ReturnType { + const it = &self.it; + const end = &self.end; + + // Reached the end + if (equal(it, end) != 0) return null; + + defer step(it); + + return ReturnType{ + .key = std.mem.sliceTo(peekName(it), 0), + .value = if (peekValue(it)) |val| Obj{ .obj = val } else null, + }; + } + }; + /////////////////////////////////// // ** Array functions ** ///////////////////////////////// diff --git a/src/main.zig b/src/main.zig index f77de52..7ced616 100644 --- a/src/main.zig +++ b/src/main.zig @@ -32,8 +32,18 @@ pub fn main() !void { //try item.persist(&db); //var jobj = item.toJson(); + var jobj = jsonItem.objectGet("tags"); defer jobj.deinit(); - std.debug.print("{s}\n", .{jobj.toString()}); + var iter = jobj.objectGetIterator(); + while(iter.next()) |*tag| { + std.debug.print("{s}", .{tag.key}); + defer std.debug.print("\n", .{}); + + if (tag.value) |*value| { + std.debug.print(" => {s}", .{value.getString()}); + } + } + }