From 804204db7cf1e8a28defd359d17fa72949e13eff Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Mon, 31 Aug 2026 23:05:16 +0200 Subject: Implement with ptrCast to make it more transparent. --- src/dict.zig | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/dict.zig (limited to 'src/dict.zig') diff --git a/src/dict.zig b/src/dict.zig new file mode 100644 index 0000000..a38d18d --- /dev/null +++ b/src/dict.zig @@ -0,0 +1,143 @@ +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 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; + } + } +}; -- cgit v1.2.3-70-g09d2