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; } } };