summaryrefslogtreecommitdiff
path: root/src/dict/Watcher.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/dict/Watcher.zig')
-rw-r--r--src/dict/Watcher.zig62
1 files changed, 62 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;
+ }
+}