summaryrefslogtreecommitdiff
path: root/src/dict
diff options
context:
space:
mode:
Diffstat (limited to 'src/dict')
-rw-r--r--src/dict/Watcher.zig62
-rw-r--r--src/dict/root.zig145
2 files changed, 207 insertions, 0 deletions
diff --git a/src/dict/Watcher.zig b/src/dict/Watcher.zig
new file mode 100644
index 0000000..317a269
--- /dev/null
+++ b/src/dict/Watcher.zig
@@ -0,0 +1,62 @@
+const std = @import("std");
+const c = @import("c");
+const zpy = @import("../root.zig");
+
+const Self = @This();
+
+id: c_int,
+
+pub const Event = enum(u32) {
+ added = c.PyDict_EVENT_ADDED,
+ modified = c.PyDict_EVENT_MODIFIED,
+ deleted = c.PyDict_EVENT_DELETED,
+ cloned = c.PyDict_EVENT_CLONED,
+ cleared = c.PyDict_EVENT_CLEARED,
+ deallocated = c.PyDict_EVENT_DEALLOCATED,
+};
+
+pub const Callback = fn (Event, *zpy.Dict, *zpy.Object, *zpy.Object) error{Exception}!void;
+
+pub fn add(callback: Callback) !Self {
+ const wrapper = struct {
+ pub fn wrapper(
+ event: c_uint,
+ dict: [*c]c.PyObject,
+ key: [*c]c.PyObject,
+ value: [*c]c.PyObject,
+ ) callconv(.c) c_int {
+ return if (std.meta.isError(callback(
+ @enumFromInt(event),
+ @ptrCast(dict),
+ @ptrCast(key),
+ @ptrCast(value),
+ ))) -1 else 0;
+ }
+ }.wrapper;
+
+ const result = c.PyDict_AddWatcher(&wrapper);
+
+ if (result == -1) {
+ return error.Exception;
+ }
+
+ return .{ .id = result };
+}
+
+pub fn clear(self: Self) !void {
+ if (c.PyDict_Clear(self.id) == -1) {
+ return error.Exception;
+ }
+}
+
+pub fn watch(self: Self, dict: *zpy.Dict) !void {
+ if (c.PyDict_Watch(self.id, @ptrCast(dict)) == -1) {
+ return error.Exception;
+ }
+}
+
+pub fn unwatch(self: Self, dict: *zpy.Dict) !void {
+ if (c.PyDict_Unwatch(self.id, @ptrCast(dict)) == -1) {
+ return error.Exception;
+ }
+}
diff --git a/src/dict/root.zig b/src/dict/root.zig
new file mode 100644
index 0000000..169add1
--- /dev/null
+++ b/src/dict/root.zig
@@ -0,0 +1,145 @@
+const std = @import("std");
+const c = @import("c");
+
+const zpy = @import("../root.zig");
+
+pub const Dict = extern struct {
+ const Self = @This();
+
+ data: c.PyObject,
+
+ pub const Watcher = @import("Watcher.zig");
+
+ pub const Key = union(enum) {
+ string: [*c]const u8,
+ object: *zpy.Object,
+ };
+
+ pub fn new() !*Self {
+ return @ptrCast(c.PyDict_New() orelse return error.Exception);
+ }
+
+ pub fn clear(self: *Self) void {
+ c.PyDict_Clear(self.object.ptr);
+ }
+
+ pub fn contains(self: *const Self, key: Key) bool {
+ return switch (key) {
+ .string => |str| c.PyDict_ContainsString(@ptrCast(self), str),
+ .object => |obj| c.PyDict_Contains(@ptrCast(self), @ptrCast(obj)),
+ } == 1;
+ }
+
+ pub fn copy(self: *const Self) *Self {
+ return @ptrCast(c.PyDict_Copy(@ptrCast(self)));
+ }
+
+ pub fn set(self: *Self, key: Key, value: zpy.Object) !void {
+ const ret = switch (key) {
+ .string => |str| c.PyDict_SetItemString(self.object.ptr, str, value.ptr),
+ .object => |obj| c.PyDict_SetItem(self.object.ptr, obj.ptr, value.ptr),
+ };
+
+ if (ret == -1) return error.Exception;
+ }
+
+ pub fn get(self: *const Self, key: Key) ?*zpy.Object {
+ return @ptrCast(switch (key) {
+ .string => |str| c.PyDict_GetItemString(@ptrCast(@constCast(self)), str),
+ .object => |obj| c.PyDict_GetItem(@ptrCast(@constCast(self)), @ptrCast(obj)),
+ });
+ }
+
+ pub fn delete(self: *Self, key: Key) !void {
+ const ret = switch (key) {
+ .string => |str| c.PyDict_DelItemString(@ptrCast(self), str),
+ .object => |obj| c.PyDict_DelItem(@ptrCast(self), @ptrCast(obj)),
+ };
+
+ if (ret == -1) return error.Exception;
+ }
+
+ pub fn setDefault(self: *Self, key: *zpy.Object, default: *zpy.Object) *zpy.Object {
+ return @ptrCast(c.PyDict_SetDefault(
+ @ptrCast(self),
+ @ptrCast(key),
+ @ptrCast(default),
+ ));
+ }
+
+ pub fn pop(self: *Self, key: Key) ?zpy.Object {
+ var result: ?*c.PyObject = undefined;
+
+ switch (key) {
+ .string => |str| c.PyDict_PopString(@ptrCast(self), str, &result),
+ .object => |obj| c.PyDict_Pop(@ptrCast(self), @ptrCast(obj), &result),
+ }
+
+ return result;
+ }
+
+ pub fn items(self: *const Self) zpy.List {
+ return @ptrCast(c.PyDict_Items(@ptrCast(@constCast(self))));
+ }
+
+ pub fn keys(self: *const Self) zpy.List {
+ return @ptrCast(c.PyDict_Keys(@ptrCast(@constCast(self))));
+ }
+
+ pub fn values(self: *const Self) zpy.List {
+ return @ptrCast(c.PyDict_Values(@ptrCast(@constCast(self))));
+ }
+
+ pub fn size(self: *const Self) usize {
+ return @intCast(c.PyDict_Size(@ptrCast(@constCast(self))));
+ }
+
+ pub const Iterator = struct {
+ dict: *Dict,
+ position: c.Py_ssize_t = 0,
+
+ pub const Pair = struct {
+ key: *zpy.Object,
+ value: *zpy.Object,
+ };
+
+ pub fn next(self: *@This()) ?Pair {
+ var pair: Pair = undefined;
+
+ if (c.PyDict_Next(
+ @ptrCast(self.dict),
+ &self.position,
+ @ptrCast(&pair.key),
+ @ptrCast(&pair.value),
+ ) == 1) {
+ return pair;
+ }
+
+ return null;
+ }
+ };
+
+ pub fn iterator(self: *Self) Iterator {
+ return .{ .dict = self };
+ }
+
+ pub fn merge(self: *Self, other: *Self) !void {
+ if (c.PyDict_Merge(
+ @ptrCast(self),
+ @ptrCast(other),
+ 0,
+ ) == -1) {
+ return error.Exception;
+ }
+ }
+
+ pub fn update(self: *Self, other: *Self) !void {
+ if (c.PyDict_Merge(
+ @ptrCast(self),
+ @ptrCast(other),
+ 1,
+ ) == -1) {
+ return error.Exception;
+ }
+ }
+};