202 lines
7.6 KiB
Zig
202 lines
7.6 KiB
Zig
const std = @import("std");
|
|
|
|
/// defaults are to be overridden by the end user
|
|
/// otherwise, simply do TableTemplate{}
|
|
/// this is a template for the cache tables
|
|
pub const TableTemplate = struct {
|
|
comptime User: type = @import("../config.zig").StoredUser,
|
|
comptime Guild: type = @import("../config.zig").StoredGuild,
|
|
comptime Channel: type = @import("../config.zig").StoredChannel,
|
|
comptime Emoji: type = @import("../config.zig").StoredEmoji,
|
|
comptime Message: type = @import("../config.zig").StoredMessage,
|
|
comptime Role: type = @import("../config.zig").StoredRole,
|
|
comptime Sticker: type = @import("../config.zig").StoredSticker,
|
|
comptime Reaction: type = @import("../config.zig").StoredReaction,
|
|
comptime Member: type = @import("../config.zig").StoredMember,
|
|
comptime Thread: type = @import("../config.zig").StoredChannel,
|
|
};
|
|
|
|
// by default this caches everything
|
|
// therefore we'll allow custom cache tables
|
|
pub fn CacheTables(comptime Table: TableTemplate) type {
|
|
return struct {
|
|
const Snowflake = @import("../structures/snowflake.zig").Snowflake;
|
|
|
|
const StoredUser: type = Table.User;
|
|
const StoredGuild: type = Table.Guild;
|
|
const StoredChannel: type = Table.Channel;
|
|
const StoredEmoji: type = Table.Emoji;
|
|
const StoredMessage: type = Table.Message;
|
|
const StoredRole: type = Table.Role;
|
|
const StoredSticker: type = Table.Sticker;
|
|
const StoredReaction: type = Table.Reaction;
|
|
const StoredMember: type = Table.Member;
|
|
const StoredThread: type = Table.Thread;
|
|
|
|
users: CacheLike(Snowflake, StoredUser),
|
|
guilds: CacheLike(Snowflake, StoredGuild),
|
|
channels: CacheLike(Snowflake, StoredChannel),
|
|
emojis: CacheLike(Snowflake, StoredEmoji),
|
|
messages: CacheLike(Snowflake, StoredMessage),
|
|
roles: CacheLike(Snowflake, StoredRole),
|
|
stickers: CacheLike(Snowflake, StoredSticker),
|
|
reactions: CacheLike(Snowflake, StoredReaction),
|
|
members: CacheLike(Snowflake, StoredMember),
|
|
threads: CacheLike(Snowflake, StoredThread),
|
|
|
|
/// you can customize with your own cache
|
|
pub fn defaults(allocator: std.mem.Allocator) CacheTables(Table) {
|
|
var users = DefaultCache(Snowflake, StoredUser).init(allocator);
|
|
var guilds = DefaultCache(Snowflake, StoredGuild).init(allocator);
|
|
var channels = DefaultCache(Snowflake, StoredChannel).init(allocator);
|
|
var emojis = DefaultCache(Snowflake, StoredEmoji).init(allocator);
|
|
var messages = DefaultCache(Snowflake, StoredMessage).init(allocator);
|
|
var roles = DefaultCache(Snowflake, StoredRole).init(allocator);
|
|
var stickers = DefaultCache(Snowflake, StoredSticker).init(allocator);
|
|
var reactions = DefaultCache(Snowflake, StoredReaction).init(allocator);
|
|
var members = DefaultCache(Snowflake, StoredMember).init(allocator);
|
|
var threads = DefaultCache(Snowflake, StoredChannel).init(allocator);
|
|
|
|
return .{
|
|
.users = users.cache(),
|
|
.guilds = guilds.cache(),
|
|
.channels = channels.cache(),
|
|
.emojis = emojis.cache(),
|
|
.messages = messages.cache(),
|
|
.roles = roles.cache(),
|
|
.stickers = stickers.cache(),
|
|
.reactions = reactions.cache(),
|
|
.members = members.cache(),
|
|
.threads = threads.cache(),
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
/// this is an extensible cache, you may implement your own
|
|
/// I recommend "zigache" to be used
|
|
pub fn CacheLike(comptime K: type, comptime V: type) type {
|
|
return struct {
|
|
ptr: *anyopaque,
|
|
putFn: *const fn(*anyopaque, K, V) anyerror!void,
|
|
getFn: *const fn(*anyopaque, K) ?V,
|
|
removeFn: *const fn(*anyopaque, K) void,
|
|
containsFn: *const fn(*anyopaque, K) bool,
|
|
countFn: *const fn(*anyopaque) usize,
|
|
|
|
pub fn put(self: CacheLike(K, V), key: K, value: V) !void {
|
|
return self.putFn(self.ptr, key, value);
|
|
}
|
|
|
|
pub fn get(self: CacheLike(K, V), key: K) ?V {
|
|
return self.getFn(self.ptr, key);
|
|
}
|
|
|
|
pub fn remove(self: CacheLike(K, V), key: K) void {
|
|
self.removeFn(self.ptr, key);
|
|
}
|
|
|
|
pub fn contains(self: CacheLike(K, V), key: K) bool {
|
|
return self.containsFn(self.ptr, key);
|
|
}
|
|
|
|
pub fn count(self: CacheLike(K, V)) usize {
|
|
return self.countFn(self.ptr);
|
|
}
|
|
|
|
pub fn init(ptr: *const anyopaque) CacheLike(K, V) {
|
|
const T = @TypeOf(ptr);
|
|
const ptr_info = @typeInfo(T);
|
|
|
|
const gen = struct {
|
|
// we don't care about order
|
|
map: std.AutoHashMap(K, V),
|
|
allocator: *std.mem.Allocator,
|
|
|
|
pub fn put(pointer: *anyopaque, key: K, value: V) anyerror!void {
|
|
const self: T = @ptrCast(@alignCast(pointer));
|
|
return ptr_info.pointer.child.put(self, key, value);
|
|
}
|
|
|
|
pub fn get(pointer: *anyopaque, key: K) ?V {
|
|
const self: T = @ptrCast(@alignCast(pointer));
|
|
return ptr_info.pointer.child.get(self, key);
|
|
}
|
|
|
|
pub fn remove(pointer: *anyopaque, key: K) void {
|
|
const self: T = @ptrCast(@alignCast(pointer));
|
|
return ptr_info.pointer.child.remove(self, key);
|
|
}
|
|
|
|
pub fn contains(pointer: *anyopaque, key: K) bool {
|
|
const self: T = @ptrCast(@alignCast(pointer));
|
|
return ptr_info.pointer.child.contains(self, key);
|
|
}
|
|
|
|
pub fn count(pointer: *anyopaque) usize {
|
|
const self: T = @ptrCast(@alignCast(pointer));
|
|
return ptr_info.pointer.child.count(self);
|
|
}
|
|
};
|
|
|
|
return .{
|
|
.ptr = ptr,
|
|
.putFn = gen.put,
|
|
.getFn = gen.get,
|
|
.removeFn = gen.remove,
|
|
.containsFn = gen.contains,
|
|
.countFn = gen.count,
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
pub fn DefaultCache(comptime K: type, comptime V: type) type {
|
|
return struct {
|
|
const Self = @This();
|
|
|
|
allocator: std.mem.Allocator,
|
|
map: std.AutoHashMap(K, V),
|
|
|
|
pub fn init(allocator: std.mem.Allocator) DefaultCache(K, V) {
|
|
return .{ .allocator = allocator, .map = .init(allocator) };
|
|
}
|
|
|
|
pub fn cache(self: *Self) CacheLike(K, V) {
|
|
return .{
|
|
.ptr = self,
|
|
.putFn = put,
|
|
.getFn = get,
|
|
.removeFn = remove,
|
|
.containsFn = contains,
|
|
.countFn = count,
|
|
};
|
|
}
|
|
|
|
pub fn put(ptr: *anyopaque, key: K, value: V) !void {
|
|
const self: *Self = @ptrCast(@alignCast(ptr));
|
|
return self.map.put(key, value);
|
|
}
|
|
|
|
pub fn get(ptr: *anyopaque, key: K) ?V {
|
|
const self: *Self = @ptrCast(@alignCast(ptr));
|
|
return self.map.get(key);
|
|
}
|
|
|
|
pub fn remove(ptr: *anyopaque, key: K) void {
|
|
const self: *Self = @ptrCast(@alignCast(ptr));
|
|
_ = self.map.remove(key);
|
|
}
|
|
|
|
pub fn contains(ptr: *anyopaque, key: K) bool {
|
|
const self: *Self = @ptrCast(@alignCast(ptr));
|
|
return self.map.contains(key);
|
|
}
|
|
|
|
pub fn count(ptr: *anyopaque) usize {
|
|
const self: *Self = @ptrCast(@alignCast(ptr));
|
|
return self.map.count();
|
|
}
|
|
};
|
|
}
|