Implement basic JSON parsing functions

This commit is contained in:
Dendy 2022-10-22 03:05:36 +02:00
parent f418aa5097
commit c5a124b100
2 changed files with 57 additions and 1 deletions

View File

@ -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 **
/////////////////////////////////

View File

@ -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()});
}
}
}