diff --git a/src/http/http.zig b/src/http/http.zig index 09eb8b6..5ddcacc 100644 --- a/src/http/http.zig +++ b/src/http/http.zig @@ -214,10 +214,12 @@ pub const FetchReq = struct { var string = std.ArrayList(u8).init(fba.allocator()); errdefer string.deinit(); - try json.stringify(object, .{}, string.writer()); + try json.stringify(object, .{ + .emit_null_optional_fields = true, + }, string.writer()); const result = try self.makeRequest(.POST, path, try string.toOwnedSlice()); - if (result.status != .ok) + if (result.status != .ok and result.status != .created and result.status != .accepted) return try json_helpers.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); return try json_helpers.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); @@ -244,7 +246,9 @@ pub const FetchReq = struct { var string = std.ArrayList(u8).init(fba.allocator()); errdefer string.deinit(); - try json.stringify(object, .{}, string.writer()); + try json.stringify(object, .{ + .emit_null_optional_fields = true, + }, string.writer()); const result = try self.makeRequestWithFiles(.POST, path, try string.toOwnedSlice(), files); if (result.status != .ok) @@ -259,7 +263,9 @@ pub const FetchReq = struct { var string = std.ArrayList(u8).init(fba.allocator()); errdefer string.deinit(); - try json.stringify(object, .{}, string.writer()); + try json.stringify(object, .{ + .emit_null_optional_fields = true, + }, string.writer()); const result = try self.makeRequest(.POST, path, try string.toOwnedSlice()); if (result.status != .no_content) diff --git a/src/shard/shard.zig b/src/shard/shard.zig index 034fd44..00abdea 100644 --- a/src/shard/shard.zig +++ b/src/shard/shard.zig @@ -24,6 +24,8 @@ const tls = std.crypto.tls; const mem = std.mem; const http = std.http; +const MAX_VALUE_LEN = 0x1000; + // todo use this to read compressed messages const zlib = @import("zlib"); const json = std.json; @@ -199,7 +201,7 @@ inline fn _connect_ws(allocator: mem.Allocator, url: []const u8) !ws.Client { .host = url, }); - var buf: [0x1000]u8 = undefined; + var buf: [MAX_VALUE_LEN]u8 = undefined; const host = try std.fmt.bufPrint(&buf, "host: {s}", .{url}); conn.handshake("/?v=10&encoding=json&compress=zlib-stream", .{ @@ -275,7 +277,7 @@ fn readMessage(self: *Self, _: anytype) (ReadError || SendError || ReconnectErro const raw = try std.json.parseFromTokenSource(GatewayPayloadType, self.allocator, &scanner, .{ .ignore_unknown_fields = true, - .max_value_len = 0x1000, + .max_value_len = MAX_VALUE_LEN, }); errdefer raw.deinit(); @@ -375,7 +377,7 @@ pub fn heartbeat(self: *Self, initial_jitter: f64) SendHeartbeatError!void { std.Thread.sleep(std.time.ns_per_ms * @as(u64, @intFromFloat(timeout))); } - self.logif("heartbeating on shard {d}", .{self.id}); + // self.logif("heartbeating on shard {d}", .{self.id}); self.rw_mutex.lock(); const last = self.heart.lastBeat; @@ -486,390 +488,390 @@ pub fn handleEvent(self: *Self, name: []const u8, payload: json.Value) !void { if (mem.eql(u8, name, "READY")) if (self.handler.ready) |event| { const ready = try json.parseFromValue(Types.Ready, self.allocator, payload, .{ .ignore_unknown_fields=true, - .max_value_len=0x1000, + .max_value_len=MAX_VALUE_LEN, }); try event(self, ready.value); }; if (mem.eql(u8, name, "APPLICATION_COMMAND_PERMISSIONS_UPDATE")) if (self.handler.application_command_permissions_update) |event| { - const acp = try json.parseFromValue(Types.ApplicationCommandPermissions, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const acp = try json.parseFromValue(Types.ApplicationCommandPermissions, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, acp.value); }; if (mem.eql(u8, name, "CHANNEL_CREATE")) if (self.handler.channel_create) |event| { - const chan = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const chan = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, chan.value); }; if (mem.eql(u8, name, "CHANNEL_UPDATE")) if (self.handler.channel_update) |event| { - const chan = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const chan = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, chan.value); }; if (mem.eql(u8, name, "CHANNEL_DELETE")) if (self.handler.channel_delete) |event| { - const chan = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const chan = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, chan.value); }; if (mem.eql(u8, name, "CHANNEL_PINS_UPDATE")) if (self.handler.channel_pins_update) |event| { - const chan_pins_update = try json.parseFromValue(Types.ChannelPinsUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const chan_pins_update = try json.parseFromValue(Types.ChannelPinsUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, chan_pins_update.value); }; if (mem.eql(u8, name, "ENTITLEMENT_CREATE")) if (self.handler.entitlement_create) |event| { - const entitlement = try json.parseFromValue(Types.Entitlement, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const entitlement = try json.parseFromValue(Types.Entitlement, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, entitlement.value); }; if (mem.eql(u8, name, "ENTITLEMENT_UPDATE")) if (self.handler.entitlement_update) |event| { - const entitlement = try json.parseFromValue(Types.Entitlement, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const entitlement = try json.parseFromValue(Types.Entitlement, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, entitlement.value); }; if (mem.eql(u8, name, "ENTITLEMENT_DELETE")) if (self.handler.entitlement_delete) |event| { - const entitlement = try json.parseFromValue(Types.Entitlement, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const entitlement = try json.parseFromValue(Types.Entitlement, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, entitlement.value); }; if (mem.eql(u8, name, "INTEGRATION_CREATE")) if (self.handler.integration_create) |event| { - const guild_id = try json.parseFromValue(Types.IntegrationCreateUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild_id = try json.parseFromValue(Types.IntegrationCreateUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild_id.value); }; if (mem.eql(u8, name, "INTEGRATION_UPDATE")) if (self.handler.integration_update) |event| { - const guild_id = try json.parseFromValue(Types.IntegrationCreateUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild_id = try json.parseFromValue(Types.IntegrationCreateUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild_id.value); }; if (mem.eql(u8, name, "INTEGRATION_DELETE")) if (self.handler.integration_delete) |event| { - const data = try json.parseFromValue(Types.IntegrationDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.IntegrationDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "INTERACTION_CREATE")) if (self.handler.interaction_create) |event| { - const interaction = try json.parseFromValue(Types.MessageInteraction, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const interaction = try json.parseFromValue(Types.MessageInteraction, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, interaction.value); }; if (mem.eql(u8, name, "INVITE_CREATE")) if (self.handler.invite_create) |event| { - const data = try json.parseFromValue(Types.InviteCreate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.InviteCreate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "INVITE_DELETE")) if (self.handler.invite_delete) |event| { - const data = try json.parseFromValue(Types.InviteDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.InviteDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "MESSAGE_CREATE")) if (self.handler.message_create) |event| { - const message = try json.parseFromValue(Types.Message, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const message = try json.parseFromValue(Types.Message, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, message.value); }; if (mem.eql(u8, name, "MESSAGE_DELETE")) if (self.handler.message_delete) |event| { - const data = try json.parseFromValue(Types.MessageDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.MessageDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "MESSAGE_UPDATE")) if (self.handler.message_update) |event| { - const message = try json.parseFromValue(Types.Message, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const message = try json.parseFromValue(Types.Message, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, message.value); }; if (mem.eql(u8, name, "MESSAGE_DELETE_BULK")) if (self.handler.message_delete_bulk) |event| { - const data = try json.parseFromValue(Types.MessageDeleteBulk, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.MessageDeleteBulk, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "MESSAGE_REACTION_ADD")) if (self.handler.message_reaction_add) |event| { - const reaction = try json.parseFromValue(Types.MessageReactionAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const reaction = try json.parseFromValue(Types.MessageReactionAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, reaction.value); }; if (mem.eql(u8, name, "MESSAGE_REACTION_REMOVE")) if (self.handler.message_reaction_remove) |event| { - const reaction = try json.parseFromValue(Types.MessageReactionRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const reaction = try json.parseFromValue(Types.MessageReactionRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, reaction.value); }; if (mem.eql(u8, name, "MESSAGE_REACTION_REMOVE_ALL")) if (self.handler.message_reaction_remove_all) |event| { - const data = try json.parseFromValue(Types.MessageReactionRemoveAll, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.MessageReactionRemoveAll, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "MESSAGE_REACTION_REMOVE_EMOJI")) if (self.handler.message_reaction_remove_emoji) |event| { - const emoji = try json.parseFromValue(Types.MessageReactionRemoveEmoji, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const emoji = try json.parseFromValue(Types.MessageReactionRemoveEmoji, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, emoji.value); }; if (mem.eql(u8, name, "GUILD_CREATE")) { const isAvailable = - try json.parseFromValue(struct { unavailable: ?bool }, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + try json.parseFromValue(struct { unavailable: ?bool }, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); if (isAvailable.value.unavailable == true) { - const guild = try json.parseFromValue(Types.Guild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild = try json.parseFromValue(Types.Guild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); if (self.handler.guild_create) |event| try event(self, guild.value); return; } - const guild = try json.parseFromValue(Types.UnavailableGuild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild = try json.parseFromValue(Types.UnavailableGuild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); if (self.handler.guild_create_unavailable) |event| try event(self, guild.value); } if (mem.eql(u8, name, "GUILD_UPDATE")) if (self.handler.guild_update) |event| { - const guild = try json.parseFromValue(Types.Guild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild = try json.parseFromValue(Types.Guild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild.value); }; if (mem.eql(u8, name, "GUILD_DELETE")) if (self.handler.guild_delete) |event| { - const guild = try json.parseFromValue(Types.UnavailableGuild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild = try json.parseFromValue(Types.UnavailableGuild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild.value); }; if (mem.eql(u8, name, "GUILD_SCHEDULED_EVENT_CREATE")) if (self.handler.guild_scheduled_event_create) |event| { - const s_event = try json.parseFromValue(Types.ScheduledEvent, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const s_event = try json.parseFromValue(Types.ScheduledEvent, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, s_event.value); }; if (mem.eql(u8, name, "GUILD_SCHEDULED_EVENT_UPDATE")) if (self.handler.guild_scheduled_event_update) |event| { - const s_event = try json.parseFromValue(Types.ScheduledEvent, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const s_event = try json.parseFromValue(Types.ScheduledEvent, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, s_event.value); }; if (mem.eql(u8, name, "GUILD_SCHEDULED_EVENT_DELETE")) if (self.handler.guild_scheduled_event_delete) |event| { - const s_event = try json.parseFromValue(Types.ScheduledEvent, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const s_event = try json.parseFromValue(Types.ScheduledEvent, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, s_event.value); }; if (mem.eql(u8, name, "GUILD_SCHEDULED_EVENT_USER_ADD")) if (self.handler.guild_scheduled_event_user_add) |event| { - const data = try json.parseFromValue(Types.ScheduledEventUserAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.ScheduledEventUserAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "GUILD_SCHEDULED_EVENT_USER_REMOVE")) if (self.handler.guild_scheduled_event_user_remove) |event| { - const data = try json.parseFromValue(Types.ScheduledEventUserRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.ScheduledEventUserRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "GUILD_MEMBER_ADD")) if (self.handler.guild_member_add) |event| { - const guild_id = try json.parseFromValue(Types.GuildMemberAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild_id = try json.parseFromValue(Types.GuildMemberAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild_id.value); }; if (mem.eql(u8, name, "GUILD_MEMBER_UPDATE")) if (self.handler.guild_member_update) |event| { - const fields = try json.parseFromValue(Types.GuildMemberUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const fields = try json.parseFromValue(Types.GuildMemberUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, fields.value); }; if (mem.eql(u8, name, "GUILD_MEMBER_REMOVE")) if (self.handler.guild_member_remove) |event| { - const user = try json.parseFromValue(Types.GuildMemberRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const user = try json.parseFromValue(Types.GuildMemberRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, user.value); }; if (mem.eql(u8, name, "GUILD_MEMBERS_CHUNK")) if (self.handler.guild_members_chunk) |event| { - const data = try json.parseFromValue(Types.GuildMembersChunk, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.GuildMembersChunk, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "GUILD_ROLE_CREATE")) if (self.handler.guild_role_create) |event| { - const role = try json.parseFromValue(Types.GuildRoleCreate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const role = try json.parseFromValue(Types.GuildRoleCreate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, role.value); }; if (mem.eql(u8, name, "GUILD_ROLE_UPDATE")) if (self.handler.guild_role_update) |event| { - const role = try json.parseFromValue(Types.GuildRoleUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const role = try json.parseFromValue(Types.GuildRoleUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, role.value); }; if (mem.eql(u8, name, "GUILD_ROLE_DELETE")) if (self.handler.guild_role_delete) |event| { - const role_id = try json.parseFromValue(Types.GuildRoleDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const role_id = try json.parseFromValue(Types.GuildRoleDelete, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, role_id.value); }; if (mem.eql(u8, name, "GUILD_DELETE")) if (self.handler.guild_delete) |event| { - const guild = try json.parseFromValue(Types.UnavailableGuild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild = try json.parseFromValue(Types.UnavailableGuild, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild.value); }; if (mem.eql(u8, name, "GUILD_BAN_ADD")) if (self.handler.guild_ban_add) |event| { - const gba = try json.parseFromValue(Types.GuildBanAddRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const gba = try json.parseFromValue(Types.GuildBanAddRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, gba.value); }; if (mem.eql(u8, name, "GUILD_BAN_REMOVE")) if (self.handler.guild_ban_remove) |event| { - const gbr = try json.parseFromValue(Types.GuildBanAddRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const gbr = try json.parseFromValue(Types.GuildBanAddRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, gbr.value); }; if (mem.eql(u8, name, "GUILD_EMOJIS_UPDATE")) if (self.handler.guild_emojis_update) |event| { - const emojis = try json.parseFromValue(Types.GuildEmojisUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const emojis = try json.parseFromValue(Types.GuildEmojisUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, emojis.value); }; if (mem.eql(u8, name, "GUILD_STICKERS_UPDATE")) if (self.handler.guild_stickers_update) |event| { - const stickers = try json.parseFromValue(Types.GuildStickersUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const stickers = try json.parseFromValue(Types.GuildStickersUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, stickers.value); }; if (mem.eql(u8, name, "GUILD_INTEGRATIONS_UPDATE")) if (self.handler.guild_integrations_update) |event| { - const guild_id = try json.parseFromValue(Types.GuildIntegrationsUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild_id = try json.parseFromValue(Types.GuildIntegrationsUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild_id.value); }; if (mem.eql(u8, name, "THREAD_CREATE")) if (self.handler.thread_create) |event| { - const thread = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const thread = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, thread.value); }; if (mem.eql(u8, name, "THREAD_UPDATE")) if (self.handler.thread_update) |event| { - const thread = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const thread = try json.parseFromValue(Types.Channel, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, thread.value); }; if (mem.eql(u8, name, "THREAD_DELETE")) if (self.handler.thread_delete) |event| { - const thread_data = try json.parseFromValue(Types.Partial(Types.Channel), self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const thread_data = try json.parseFromValue(Types.Partial(Types.Channel), self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, thread_data.value); }; if (mem.eql(u8, name, "THREAD_LIST_SYNC")) if (self.handler.thread_list_sync) |event| { - const data = try json.parseFromValue(Types.ThreadListSync, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.ThreadListSync, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "THREAD_MEMBER_UPDATE")) if (self.handler.thread_member_update) |event| { - const guild_id = try json.parseFromValue(Types.ThreadMemberUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const guild_id = try json.parseFromValue(Types.ThreadMemberUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, guild_id.value); }; if (mem.eql(u8, name, "THREAD_MEMBERS_UPDATE")) if (self.handler.thread_members_update) |event| { - const data = try json.parseFromValue(Types.ThreadMembersUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.ThreadMembersUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "TYPING_START")) if (self.handler.typing_start) |event| { - const data = try json.parseFromValue(Types.TypingStart, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.TypingStart, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "USER_UPDATE")) if (self.handler.user_update) |event| { - const user = try json.parseFromValue(Types.User, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const user = try json.parseFromValue(Types.User, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, user.value); }; if (mem.eql(u8, name, "PRESENCE_UPDATE")) if (self.handler.presence_update) |event| { - const pu = try json.parseFromValue(Types.PresenceUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const pu = try json.parseFromValue(Types.PresenceUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, pu.value); }; if (mem.eql(u8, name, "MESSSAGE_POLL_VOTE_ADD")) if (self.handler.message_poll_vote_add) |event| { - const data = try json.parseFromValue(Types.PollVoteAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.PollVoteAdd, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "MESSSAGE_POLL_VOTE_REMOVE")) if (self.handler.message_poll_vote_remove) |event| { - const data = try json.parseFromValue(Types.PollVoteRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const data = try json.parseFromValue(Types.PollVoteRemove, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, data.value); }; if (mem.eql(u8, name, "WEBHOOKS_UPDATE")) if (self.handler.webhooks_update) |event| { - const fields = try json.parseFromValue(Types.WebhookUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const fields = try json.parseFromValue(Types.WebhookUpdate, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, fields.value); }; if (mem.eql(u8, name, "STAGE_INSTANCE_CREATE")) if (self.handler.stage_instance_create) |event| { - const stage = try json.parseFromValue(Types.StageInstance, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const stage = try json.parseFromValue(Types.StageInstance, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, stage.value); }; if (mem.eql(u8, name, "STAGE_INSTANCE_UPDATE")) if (self.handler.stage_instance_update) |event| { - const stage = try json.parseFromValue(Types.StageInstance, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const stage = try json.parseFromValue(Types.StageInstance, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, stage.value); }; if (mem.eql(u8, name, "STAGE_INSTANCE_DELETE")) if (self.handler.stage_instance_delete) |event| { - const stage = try json.parseFromValue(Types.StageInstance, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const stage = try json.parseFromValue(Types.StageInstance, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, stage.value); }; if (mem.eql(u8, name, "AUTO_MODERATION_RULE_CREATE")) if (self.handler.auto_moderation_rule_create) |event| { - const rule = try json.parseFromValue(Types.AutoModerationRule, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const rule = try json.parseFromValue(Types.AutoModerationRule, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, rule.value); }; if (mem.eql(u8, name, "AUTO_MODERATION_RULE_UPDATE")) if (self.handler.auto_moderation_rule_update) |event| { - const rule = try json.parseFromValue(Types.AutoModerationRule, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const rule = try json.parseFromValue(Types.AutoModerationRule, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, rule.value); }; if (mem.eql(u8, name, "AUTO_MODERATION_RULE_DELETE")) if (self.handler.auto_moderation_rule_delete) |event| { - const rule = try json.parseFromValue(Types.AutoModerationRule, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=0x1000}); + const rule = try json.parseFromValue(Types.AutoModerationRule, self.allocator, payload, .{.ignore_unknown_fields=true, .max_value_len=MAX_VALUE_LEN}); try event(self, rule.value); }; if (mem.eql(u8, name, "AUTO_MODERATION_ACTION_EXECUTION")) if (self.handler.auto_moderation_action_execution) |event| { - const ax = try json.parseFromValue(Types.AutoModerationActionExecution, self.allocator, payload, .{ .ignore_unknown_fields=true, .max_value_len = 0x1000, + const ax = try json.parseFromValue(Types.AutoModerationActionExecution, self.allocator, payload, .{ .ignore_unknown_fields=true, .max_value_len = MAX_VALUE_LEN, }); try event(self, ax.value); diff --git a/src/structures/shared.zig b/src/structures/shared.zig index 046d51d..827f564 100644 --- a/src/structures/shared.zig +++ b/src/structures/shared.zig @@ -22,6 +22,10 @@ pub const PresenceStatus = enum { dnd, idle, offline, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/user#user-object-premium-types @@ -30,6 +34,10 @@ pub const PremiumTypes = enum { NitroClassic, Nitro, NitroBasic, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/user#user-object-user-flags @@ -522,6 +530,10 @@ pub const MessageComponentTypes = enum(u4) { SelectMenuUsersAndRoles, /// Select menu for channels SelectMenuChannels, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const TextStyles = enum(u4) { @@ -529,6 +541,10 @@ pub const TextStyles = enum(u4) { Short = 1, /// Intended for much longer inputs Paragraph = 2, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/interactions/message-components#buttons-button-styles @@ -545,6 +561,10 @@ pub const ButtonStyles = enum(u4) { Link, /// A blurple button to show a Premium item in the shop Premium, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types @@ -555,6 +575,10 @@ pub const AllowedMentionsTypes = enum { users, /// Controls \@everyone and \@here mentions everyone, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types @@ -565,6 +589,10 @@ pub const WebhookTypes = enum(u4) { ChannelFollower, /// Application webhooks are webhooks used with Interactions Application, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/channel#embed-object-embed-types @@ -577,6 +605,10 @@ pub const EmbedTypes = enum { article, link, poll_res, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level @@ -585,6 +617,10 @@ pub const DefaultMessageNotificationLevels = enum { AllMessages, /// Members will receive notifications only for messages that \@mention them by default OnlyMentions, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level @@ -595,6 +631,10 @@ pub const ExplicitContentFilterLevels = enum { MembersWithoutRoles, /// Media content sent by all members will be scanned AllMembers, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-verification-level @@ -609,6 +649,10 @@ pub const VerificationLevels = enum { High, /// Must have a verified phone number VeryHigh, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-guild-features @@ -665,6 +709,10 @@ pub const GuildFeatures = enum { RAID_ALERTS_DISABLED, /// Guild is using the old permissions configuration behavior APPLICATION_COMMAND_PERMISSIONS_V2, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-mfa-level @@ -673,6 +721,10 @@ pub const MfaLevels = enum { None, /// Guild has a 2FA requirement for moderation actions Elevated, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags @@ -722,6 +774,10 @@ pub const PremiumTiers = enum { Tier2, /// Guild has unlocked Server Boost level 3 perks Tier3, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/guild#guild-object-guild-nsfw-level @@ -730,67 +786,53 @@ pub const GuildNsfwLevel = enum { Explicit, Safe, AgeRestricted, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/channel#channel-object-channel-types -pub const ChannelTypes = packed struct { - pub fn toRaw(self: ChannelTypes) u32 { - return @bitCast(self); - } - - pub fn fromRaw(raw: u32) ChannelTypes { - return @bitCast(raw); - } - - pub fn jsonParse(allocator: std.mem.Allocator, src: anytype, _: std.json.ParseOptions) !@This() { - const value = try std.json.innerParse(std.json.Value, allocator, src, .{ - .ignore_unknown_fields = true, - .max_value_len = 0x1000, - }); - if (value != .integer) @panic("Invalid value for bitfield"); - - return fromRaw(@intCast(value.integer)); - } - - pub fn jsonParseFromValue(_: std.mem.Allocator, src: std.json.Value, _: std.json.ParseOptions) @This() { - if (src != .integer) @panic("Invalid value for bitfield"); - return fromRaw(@intCast(src.integer)); - } - - +pub const ChannelTypes = enum(u16) { /// A text channel within a server - GuildText: bool = false, + GuildText, /// A direct message between users - DM: bool = false, + DM, /// A voice channel within a server - GuildVoice: bool = false, + GuildVoice, /// A direct message between multiple users - GroupDm: bool = false, + GroupDm, /// An organizational category that contains up to 50 channels - GuildCategory: bool = false, + GuildCategory, /// A channel that users can follow and crosspost into their own server - GuildAnnouncement: bool = false, - _pad: u4 = 0, + GuildAnnouncement, /// A temporary sub-channel within a GUILD_ANNOUNCEMENT channel - AnnouncementThread: bool = false, + AnnouncementThread = 10, /// A temporary sub-channel within a GUILD_TEXT or GUILD_FORUM channel - PublicThread: bool = false, + PublicThread, /// A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission - PrivateThread: bool = false, + PrivateThread, /// A voice channel for hosting events with an audience - GuildStageVoice: bool = false, + GuildStageVoice, /// A channel in a hub containing the listed servers - GuildDirectory: bool = false, + GuildDirectory, /// A channel which can only contains threads - GuildForum: bool = false, + GuildForum, /// Channel that can only contain threads, similar to GUILD_FORUM channels - GuildMedia: bool = false, - _pad1: u15 = 0, + GuildMedia, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const OverwriteTypes = enum { Role, Member, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const VideoQualityModes = enum(u4) { @@ -798,6 +840,10 @@ pub const VideoQualityModes = enum(u4) { Auto = 1, /// 720p Full, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-types @@ -808,6 +854,10 @@ pub const ActivityTypes = enum(u4) { Watching = 3, Custom = 4, Competing = 5, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/channel#message-object-message-types @@ -849,6 +899,10 @@ pub const MessageTypes = enum(u8) { GuildIncidentReportFalseAlarm, PurchaseNotification = 44, PollResult = 46, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/channel#message-object-message-activity-types @@ -857,6 +911,10 @@ pub const MessageActivityTypes = enum(u4) { Spectate = 2, Listen = 3, JoinRequest = 5, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types @@ -865,6 +923,10 @@ pub const StickerTypes = enum(u4) { Standard = 1, /// a sticker uploaded to a guild for the guild's members Guild = 2, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types @@ -873,6 +935,10 @@ pub const StickerFormatTypes = enum(u4) { APng, Lottie, Gif, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype @@ -882,6 +948,10 @@ pub const InteractionTypes = enum(u4) { MessageComponent = 3, ApplicationCommandAutocomplete = 4, ModalSubmit = 5, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype @@ -897,6 +967,10 @@ pub const ApplicationCommandOptionTypes = enum(u4) { Mentionable, Number, Attachment, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events @@ -1027,17 +1101,29 @@ pub const AuditLogEvents = enum(u4) { HomeSettingsCreate = 190, /// Guild Server Guide was updated HomeSettingsUpdate, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const ScheduledEventPrivacyLevel = enum(u4) { /// the scheduled event is only accessible to guild members GuildOnly = 2, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const ScheduledEventEntityType = enum(u4) { StageInstance = 1, Voice, External, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const ScheduledEventStatus = enum(u4) { @@ -1045,12 +1131,20 @@ pub const ScheduledEventStatus = enum(u4) { Active, Completed, Canceled, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/resources/invite#invite-object-target-user-types pub const TargetTypes = enum(u4) { Stream = 1, EmbeddedApplication, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const ApplicationCommandTypes = enum(u4) { @@ -1062,12 +1156,20 @@ pub const ApplicationCommandTypes = enum(u4) { Message, /// A UI-based command that represents the primary way to invoke an app's Activity PrimaryEntryPoint, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const ApplicationCommandPermissionTypes = enum(u4) { Role = 1, User, Channel, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags @@ -1331,6 +1433,10 @@ pub const GatewayCloseEventCodes = enum(u16) { InvalidIntents, /// You sent a disallowed intent for a [Gateway Intent](https://discord.com/developers/docs/topics/gateway#gateway-intents). You may have tried to specify an intent that you [have not enabled or are not approved for](https://discord.com/developers/docs/topics/gateway#privileged-intents). DisallowedIntents, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes @@ -1357,6 +1463,10 @@ pub const GatewayOpcodes = enum(u4) { Hello, /// Sent in response to receiving a heartbeat to acknowledge that it has been received. HeartbeatACK, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const GatewayDispatchEventNames = union(enum) { @@ -1458,6 +1568,10 @@ pub const InteractionResponseTypes = enum(u4) { /// @remarks /// Only available for apps with Activities enabled LaunchActivity = 12, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const SortOrderTypes = enum { @@ -1465,6 +1579,10 @@ pub const SortOrderTypes = enum { LatestActivity, /// Sort forum posts by creation time (from most recent to oldest) CreationDate, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; pub const ForumLayout = enum { @@ -1474,6 +1592,10 @@ pub const ForumLayout = enum { ListView, /// Display posts as a collection of tiles. GalleryView, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@intFromEnum(self)}); + } }; /// https://discord.com/developers/docs/reference#image-formatting @@ -1662,4 +1784,8 @@ pub const InteractionContextType = enum { BotDm, /// Interaction can be used within Group DMs and DMs other than the app's bot user PrivateChannel, + + pub fn jsonStringify(self: @This(), writer: anytype) !void { + try writer.print("{d}", .{@enumFromInt(self)}); + } }; diff --git a/src/utils/json.zig b/src/utils/json.zig index bf25450..e005b51 100644 --- a/src/utils/json.zig +++ b/src/utils/json.zig @@ -17,6 +17,8 @@ const std = @import("std"); const json = std.json; +const MAX_VALUE_LEN = 0x1000; + /// a hashmap for key value pairs /// where every key is an int /// @@ -49,7 +51,7 @@ pub fn AssociativeArray(comptime E: type, comptime V: type) type { const value = try std.json.innerParse(std.json.Value, allocator, src, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100 + .max_value_len = MAX_VALUE_LEN }); var iterator = value.object.iterator(); @@ -63,7 +65,7 @@ pub fn AssociativeArray(comptime E: type, comptime V: type) type { const val = try std.json.parseFromValueLeaky(V, allocator, v, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, }); map.put(@enumFromInt(int), val); @@ -98,7 +100,7 @@ pub fn DiscriminatedUnion(comptime U: type, comptime key: []const u8) type { const value = try std.json.innerParse(std.json.Value, allocator, src, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100 + .max_value_len = MAX_VALUE_LEN }); const discriminator = value.object.get(key) orelse @@ -114,7 +116,7 @@ pub fn DiscriminatedUnion(comptime U: type, comptime key: []const u8) type { comptime std.debug.assert(@hasField(T, key)); u = @unionInit(U, field.name, try std.json.innerParse(T, allocator, src, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, })); } } @@ -131,7 +133,7 @@ pub fn Record(comptime T: type) type { pub fn jsonParse(allocator: std.mem.Allocator, src: anytype, _: json.ParseOptions) !@This() { const value = try std.json.innerParse(std.json.Value, allocator, src, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100 + .max_value_len = MAX_VALUE_LEN }); errdefer value.object.deinit(); @@ -148,7 +150,7 @@ pub fn Record(comptime T: type) type { // errdefer v.deinit(allocator); try map.put(allocator, k, try std.json.parseFromValue(T, allocator, v, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, })); } @@ -229,12 +231,12 @@ pub fn parseRight(comptime L: type, comptime R: type, child_allocator: std.mem.A const allocator = owned.arena.allocator(); const value = try json.parseFromSliceLeaky(json.Value, allocator, data, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, }); owned.value = .{ .right = try json.parseFromValueLeaky(R, allocator, value, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, }) }; errdefer owned.arena.deinit(); @@ -252,12 +254,12 @@ pub fn parseLeft(comptime L: type, comptime R: type, child_allocator: std.mem.Al const allocator = owned.arena.allocator(); const value = try json.parseFromSliceLeaky(json.Value, allocator, data, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, }); owned.value = .{ .left = try json.parseFromValueLeaky(L, allocator, value, .{ .ignore_unknown_fields = true, - .max_value_len = 0x100, + .max_value_len = MAX_VALUE_LEN, }) }; errdefer owned.arena.deinit(); diff --git a/test/test.zig b/test/test.zig index a709567..8b4ee86 100644 --- a/test/test.zig +++ b/test/test.zig @@ -25,12 +25,43 @@ fn ready(_: *Shard, payload: Discord.Ready) !void { } fn message_create(_: *Shard, message: Discord.Message) !void { - if (message.content != null and std.ascii.eqlIgnoreCase(message.content.?, "!hi")) { - var result = try session.api.sendMessage(message.channel_id, .{ .content = "hi :)" }); - defer result.deinit(); + if (message.content != null) { + if (std.ascii.eqlIgnoreCase(message.content.?, "!hi")) { + var result = try session.api.sendMessage(message.channel_id, .{ .content = "hi :)" }); + defer result.deinit(); - const m = result.value.unwrap(); - std.debug.print("sent: {?s}\n", .{m.content}); + const m = result.value.unwrap(); + std.debug.print("sent: {?s}\n", .{m.content}); + } + + if (std.ascii.eqlIgnoreCase(message.content.?, "!ping")) { + var result = try session.api.sendMessage(message.channel_id, .{ .content = "pong" }); + defer result.deinit(); + const m = result.value.unwrap(); + std.debug.print("sent: {?s}\n", .{m.content}); + } + + if (std.ascii.eqlIgnoreCase(message.content.?, "!create-channel")) { + var result = try session.api.createChannel(message.guild_id.?, .{ + .name = "test-channel", + .type = .GuildText, + .topic = null, + .bitrate = null, + .permission_overwrites = null, + .nsfw = false, + .default_reaction_emoji = null, + .available_tags = null, + }); + defer result.deinit(); + switch (result.value) { + .left => |err| { + std.debug.print("error creating channel: {any}\n", .{err}); + }, + .right => |channel| { + std.debug.print("created channel: {?s}\n", .{channel.name}); + }, + } + } } }