diff --git a/README.md b/README.md index 68b6866..cf7f6ed 100644 --- a/README.md +++ b/README.md @@ -5,34 +5,42 @@ A high-performance bleeding edge Discord library in Zig, featuring full API cove * 100% API Coverage & Fully Typed: Offers complete access to Discord's API with strict typing for reliable and safe code. * High Performance: Faster than whichever library you can name (WIP) * Flexible Payload Parsing: Supports payload parsing through both zlib and zstd*. +* Proper error handling ```zig -const Client = @import("discord.zig").Client; -const Shard = @import("discord.zig").Shard; -const Discord = @import("discord.zig"); -const Intents = Discord.Intents; const std = @import("std"); +const Discord = @import("discord.zig"); +const Shard = Discord.Shard; +const Intents = Discord.Intents; -fn ready(_: *Shard, payload: Discord.Ready) void { +fn ready(_: *Shard, payload: Discord.Ready) !void { std.debug.print("logged in as {s}\n", .{payload.user.username}); } -fn message_create(_: *Shard, message: Discord.Message) void { - std.debug.print("captured: {?s}\n", .{ message.content }); +fn message_create(session: *Shard, message: Discord.Message) !void { + if (message.content) |mc| if (std.ascii.eqlIgnoreCase(mc, "!hi")) { + var result = try session.sendMessage(message.channel_id, .{ .content = "discord.zig best lib" }); + defer result.deinit(); + + switch (result.value) { + .left => |e| std.debug.panic("Error: {d}\r{s}\n", .{ e.code, e.message }), // or you may tell the end user the error + .right => |m| std.debug.print("Sent: {?s} sent by {s}\n", .{ m.content, m.author.username }), + } + }; } pub fn main() !void { - var handler = Client.init(allocator); + var gpa = std.heap.GeneralPurposeAllocator(.{ .stack_trace_frames = 9999 }){}; + var handler = Discord.init(gpa.allocator()); try handler.start(.{ - .token = std.posix.getenv("TOKEN") orelse unreachable, - .intents = Intents.fromRaw(37379), + .token = std.posix.getenv("TOKEN").?, // or your token + .intents = Intents.fromRaw(53608447), // all intents .run = .{ .message_create = &message_create, .ready = &ready }, .log = .yes, .options = .{}, }); errdefer handler.deinit(); } - ``` ## Installation ```zig @@ -60,6 +68,7 @@ Contributions are welcome! Please open an issue or pull request if you'd like to |-------------------------------------------------------------|--------| | stablish good sharding support with buckets | ✅ | | finish the event coverage roadmap | ✅ | +| proper error handling | ✅ | | use the priority queues for handling ratelimits (half done) | ❌ | | make the library scalable with a gateway proxy | ❌ | | get a cool logo | ❌ | diff --git a/build.zig b/build.zig index 8952a59..00a534d 100644 --- a/build.zig +++ b/build.zig @@ -32,7 +32,7 @@ pub fn build(b: *std.Build) void { const marin = b.addExecutable(.{ .name = "marin", - .root_source_file = b.path("src/test.zig"), + .root_source_file = b.path("test/test.zig"), .target = target, .optimize = optimize, .link_libc = true, diff --git a/src/errors.zig b/src/errors.zig new file mode 100644 index 0000000..135a50b --- /dev/null +++ b/src/errors.zig @@ -0,0 +1,17 @@ +/// an error ought to be matched by `code` for providing the end user with sensible errors +pub const DiscordErrorPayload = struct { + /// cryptic error code, eg: `MISSING_PERMISSIONS` + code: []const u8, + /// human readable error message + message: []const u8, +}; + +pub const DiscordError = struct { + code: usize, + message: []const u8, + errors: ?struct { _errors: []DiscordErrorPayload }, +}; + +pub fn Result(comptime T: type) type { + return @import("json.zig").OwnedEither(DiscordError, T); +} diff --git a/src/http.zig b/src/http.zig index 9740d4b..e3f9403 100644 --- a/src/http.zig +++ b/src/http.zig @@ -19,6 +19,8 @@ const mem = std.mem; const http = std.http; const json = std.json; const zjson = @import("json.zig"); +pub const Result = @import("errors.zig").Result; +pub const DiscordError = @import("errors.zig").DiscordError; pub const BASE_URL = "https://discord.com/api/v10"; @@ -95,22 +97,24 @@ pub const FetchReq = struct { return query.toOwnedSlice(self.allocator); } - pub fn get(self: *FetchReq, comptime T: type, path: []const u8) !zjson.Owned(T) { + pub fn get(self: *FetchReq, comptime T: type, path: []const u8) !Result(T) { const result = try self.makeRequest(.GET, path, null); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - const output = try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + const output = try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); return output; } - pub fn delete(self: *FetchReq, path: []const u8) !void { + pub fn delete(self: *FetchReq, path: []const u8) !Result(void) { const result = try self.makeRequest(.DELETE, path, null); if (result.status != .no_content) - return error.FailedRequest; + return try zjson.tryParse(DiscordError, void, self.allocator, try self.body.toOwnedSlice()); + + return .ok({}); } - pub fn patch(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !zjson.Owned(T) { + pub fn patch(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !Result(T) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -120,9 +124,9 @@ pub const FetchReq = struct { const result = try self.makeRequest(.PATCH, path, try string.toOwnedSlice()); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } pub fn patch2(self: *FetchReq, path: []const u8, object: anytype) !void { @@ -135,10 +139,12 @@ pub const FetchReq = struct { const result = try self.makeRequest(.PATCH, path, try string.toOwnedSlice()); if (result.status != .no_content) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, void, self.allocator, try self.body.toOwnedSlice()); + + return .ok({}); } - pub fn put(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !zjson.Owned(T) { + pub fn put(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !Result(T) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -148,12 +154,12 @@ pub const FetchReq = struct { const result = try self.makeRequest(.PUT, path, try string.toOwnedSlice()); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } - pub fn put2(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !?zjson.Owned(T) { + pub fn put2(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !Result(T) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -163,28 +169,30 @@ pub const FetchReq = struct { const result = try self.makeRequest(.PUT, path, try string.toOwnedSlice()); if (result.status == .no_content) - return null; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } - pub fn put3(self: *FetchReq, path: []const u8) !void { + pub fn put3(self: *FetchReq, path: []const u8) !Result(void) { const result = try self.makeRequest(.PUT, path, null); if (result.status != .no_content) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, void, self.allocator, try self.body.toOwnedSlice()); + + return .ok({}); } - pub fn put4(self: *FetchReq, comptime T: type, path: []const u8) !zjson.Owned(T) { + pub fn put4(self: *FetchReq, comptime T: type, path: []const u8) !Result(T) { const result = try self.makeRequest(.PUT, path, null); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } - pub fn put5(self: *FetchReq, path: []const u8, object: anytype) !void { + pub fn put5(self: *FetchReq, path: []const u8, object: anytype) !Result(void) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -194,10 +202,12 @@ pub const FetchReq = struct { const result = try self.makeRequest(.PUT, path, try self.body.toOwnedSlice()); if (result.status != .no_content) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, void, self.allocator, try self.body.toOwnedSlice()); + + return .ok({}); } - pub fn post(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !zjson.Owned(T) { + pub fn post(self: *FetchReq, comptime T: type, path: []const u8, object: anytype) !Result(T) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -207,18 +217,18 @@ pub const FetchReq = struct { const result = try self.makeRequest(.POST, path, try string.toOwnedSlice()); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } - pub fn post2(self: *FetchReq, comptime T: type, path: []const u8) !zjson.Owned(T) { + pub fn post2(self: *FetchReq, comptime T: type, path: []const u8) !Result(T) { const result = try self.makeRequest(.POST, path, null); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } pub fn post3( @@ -227,7 +237,7 @@ pub const FetchReq = struct { path: []const u8, object: anytype, files: []const FileData, - ) !zjson.Owned(T) { + ) !Result(T) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -237,12 +247,12 @@ pub const FetchReq = struct { const result = try self.makeRequestWithFiles(.POST, path, try string.toOwnedSlice(), files); if (result.status != .ok) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); - return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); + return try zjson.parseRight(DiscordError, T, self.allocator, try self.body.toOwnedSlice()); } - pub fn post4(self: *FetchReq, path: []const u8, object: anytype) !void { + pub fn post4(self: *FetchReq, path: []const u8, object: anytype) !Result(void) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -252,14 +262,18 @@ pub const FetchReq = struct { const result = try self.makeRequest(.POST, path, try string.toOwnedSlice()); if (result.status != .no_content) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, void, self.allocator, try self.body.toOwnedSlice()); + + return .ok({}); } - pub fn post5(self: *FetchReq, path: []const u8) !void { + pub fn post5(self: *FetchReq, path: []const u8) !Result(void) { const result = try self.makeRequest(.POST, path, null); if (result.status != .no_content) - return error.FailedRequest; + return try zjson.parseLeft(DiscordError, void, self.allocator, try self.body.toOwnedSlice()); + + return .ok({}); } pub fn makeRequest( diff --git a/src/json.zig b/src/json.zig index a6da487..b7a3ae9 100644 --- a/src/json.zig +++ b/src/json.zig @@ -76,10 +76,23 @@ pub fn ParseResult(comptime T: type) type { } /// Either a b = Left a | Right b -pub fn Either(comptime T: type, comptime U: type) type { +pub fn Either(comptime L: type, comptime R: type) type { return union(enum) { - left: T, - right: U, + left: L, + right: R, + + /// always returns .right + pub fn unwrap(self: @This()) R { + // discord.zig specifics + if (@hasField(L, "code") and @hasField(L, "message") and self.value == .left) + std.debug.panic("Error: {d}, {s}\n", .{ self.value.left.code, self.value.left.message }); + + // for other libraries, it'll do this + if (self.value == .left) + std.debug.panic("Error: {any}\n", .{self.value.left}); + + return self.value.right; + } pub fn is(self: @This(), tag: std.meta.Tag(@This())) bool { return self == tag; @@ -1141,6 +1154,30 @@ pub fn Owned(comptime T: type) type { }; } +/// same as `Owned` but instead it handles 2 different values, generally `.right` is the correct one and `left` the error type +pub fn OwnedEither(comptime L: type, comptime R: type) type { + // if (@typeInfo(Struct) != .@"struct") @compileError("expected a `struct` type"); + + return struct { + value: Either(L, R), + arena: *std.heap.ArenaAllocator, + + pub fn ok(ok_value: R) @This() { + return .{ .value = ok_value }; + } + + pub fn err(err_value: L) @This() { + return .{ .value = err_value }; + } + + pub fn deinit(self: @This()) void { + const allocator = self.arena.child_allocator; + self.arena.deinit(); + allocator.destroy(self.arena); + } + }; +} + /// parse any string containing a JSON object root `{...}` /// casts the value into `T` pub fn parse(comptime T: type, child_allocator: mem.Allocator, data: []const u8) ParserError!Owned(T) { @@ -1157,6 +1194,36 @@ pub fn parse(comptime T: type, child_allocator: mem.Allocator, data: []const u8) return owned; } +/// same as `parse` +pub fn parseLeft(comptime L: type, comptime R: type, child_allocator: mem.Allocator, data: []const u8) ParserError!OwnedEither(L, R) { + var owned: OwnedEither(L, R) = .{ + .arena = try child_allocator.create(std.heap.ArenaAllocator), + .value = undefined, + }; + owned.arena.* = std.heap.ArenaAllocator.init(child_allocator); + const allocator = owned.arena.allocator(); + const value = try ultimateParserAssert(data, allocator); + owned.value = .{ .left = try parseInto(L, allocator, value) }; + errdefer owned.arena.deinit(); + + return owned; +} + +/// same as `parse` +pub fn parseRight(comptime L: type, comptime R: type, child_allocator: mem.Allocator, data: []const u8) ParserError!OwnedEither(L, R) { + var owned: OwnedEither(L, R) = .{ + .arena = try child_allocator.create(std.heap.ArenaAllocator), + .value = undefined, + }; + owned.arena.* = std.heap.ArenaAllocator.init(child_allocator); + const allocator = owned.arena.allocator(); + const value = try ultimateParserAssert(data, allocator); + owned.value = .{ .right = try parseInto(R, allocator, value) }; + errdefer owned.arena.deinit(); + + return owned; +} + /// a hashmap for key value pairs pub fn Record(comptime T: type) type { return struct { diff --git a/src/shard.zig b/src/shard.zig index b9d67ce..9bc4df5 100644 --- a/src/shard.zig +++ b/src/shard.zig @@ -28,6 +28,7 @@ const http = std.http; const zlib = @import("zlib"); const zjson = @import("json.zig"); +const Result = @import("errors.zig").Result; const Self = @This(); const IdentifyProperties = @import("internal.zig").IdentifyProperties; @@ -796,7 +797,7 @@ pub const RequestFailedError = zjson.ParserError || MakeRequestError || error{Fa /// If operating on a guild channel, this endpoint requires the current user to have the `VIEW_CHANNEL` permission. /// If the channel is a voice channel, they must also have the `CONNECT` permission. /// If the current user is missing the `READ_MESSAGE_HISTORY` permission in the channel, then no messages will be returned. -pub fn fetchMessages(self: *Self, channel_id: Snowflake, query: Types.GetMessagesQuery) RequestFailedError!zjson.Owned([]Types.Message) { +pub fn fetchMessages(self: *Self, channel_id: Snowflake, query: Types.GetMessagesQuery) RequestFailedError!Result([]Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages", .{channel_id.into()}); @@ -816,7 +817,7 @@ pub fn fetchMessages(self: *Self, channel_id: Snowflake, query: Types.GetMessage /// Returns a message object on success. /// If operating on a guild channel, this endpoint requires the current user to have the `VIEW_CHANNEL` and `READ_MESSAGE_HISTORY` permissions. /// If the channel is a voice channel, they must also have the `CONNECT` permission. -pub fn fetchMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake) RequestFailedError!zjson.Owned(Types.Message) { +pub fn fetchMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake) RequestFailedError!Result(Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}", .{ channel_id.into(), message_id.into() }); @@ -843,7 +844,7 @@ pub fn sendMessage( self: *Self, channel_id: Snowflake, create_message: Partial(Types.CreateMessage), -) RequestFailedError!zjson.Owned(Types.Message) { +) RequestFailedError!Result(Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages", .{channel_id.into()}); @@ -909,7 +910,7 @@ pub fn sendMessageWithFiles( /// This endpoint requires the `SEND_MESSAGES` permission, if the current user sent the message, or additionally the `MANAGE_MESSAGES` permission, for all other messages, to be present for the current user. /// Returns a message object. /// Fires a Message Update Gateway event. -pub fn crosspostMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake) RequestFailedError!zjson.Owned(Types.Message) { +pub fn crosspostMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake) RequestFailedError!Result(Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/crosspost", .{ channel_id.into(), message_id.into() }); @@ -930,7 +931,7 @@ pub fn react( channel_id: Snowflake, message_id: Snowflake, emoji: Types.Emoji, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/reactions/{s}:{d}/@me", .{ channel_id.into(), @@ -942,7 +943,7 @@ pub fn react( var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.put3(path); + return req.put3(path); } /// Delete a reaction the current user has made for the message. @@ -953,7 +954,7 @@ pub fn deleteOwnReaction( channel_id: Snowflake, message_id: Snowflake, emoji: Types.Emoji, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/reactions/{s}:{d}/@me", .{ channel_id.into(), @@ -965,7 +966,7 @@ pub fn deleteOwnReaction( var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Get a list of users that reacted with this emoji. @@ -976,7 +977,7 @@ pub fn fetchReactions( channel_id: Snowflake, message_id: Snowflake, emoji: Types.Emoji, -) RequestFailedError!zjson.Owned([]Types.User) { +) RequestFailedError!Result([]Types.User) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/reactions/{s}:{d}", .{ channel_id.into(), @@ -999,14 +1000,14 @@ pub fn nukeReactions( self: *Self, channel_id: Snowflake, message_id: Snowflake, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/reactions", .{ channel_id.into(), message_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Deletes all the reactions for a given emoji on a message. @@ -1017,7 +1018,7 @@ pub fn nukeReactionsFor( channel_id: Snowflake, message_id: Snowflake, emoji: Types.Emoji, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/reactions/{s}:{d}", .{ channel_id.into(), @@ -1029,7 +1030,7 @@ pub fn nukeReactionsFor( var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Delete a message. @@ -1037,7 +1038,7 @@ pub fn nukeReactionsFor( /// Returns a 204 empty response on success. /// Fires a Message Delete Gateway event. /// TODO: implement audit-log header? -pub fn deleteMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn deleteMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}", .{ channel_id.into(), message_id.into() }); @@ -1046,7 +1047,7 @@ pub fn deleteMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } /// Delete multiple messages in a single request. @@ -1055,7 +1056,7 @@ pub fn deleteMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, /// Fires a Message Delete Bulk Gateway event. /// /// Any message IDs given that do not exist or are invalid will count towards the minimum and maximum message count (currently 2 and 100 respectively). -pub fn bulkDeleteMessages(self: *Self, channel_id: Snowflake, messages: []Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn bulkDeleteMessages(self: *Self, channel_id: Snowflake, messages: []Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/bulk-delete", .{channel_id.into()}); @@ -1064,7 +1065,7 @@ pub fn bulkDeleteMessages(self: *Self, channel_id: Snowflake, messages: []Snowfl try req.addHeader("X-Audit-Log-Reason", reason); - try req.post4(path, .{ .messages = messages }); + return req.post4(path, .{ .messages = messages }); } /// Edit a previously sent message. @@ -1079,7 +1080,7 @@ pub fn bulkDeleteMessages(self: *Self, channel_id: Snowflake, messages: []Snowfl /// /// Returns a message object. Fires a Message Update Gateway event. /// @remarks Starting with API v10, the attachments array must contain all attachments that should be present after edit, including retained and new attachments provided in the request body. -pub fn editMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, edit_message: Partial(Types.CreateMessage)) RequestFailedError!zjson.Owned(Types.Message) { +pub fn editMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, edit_message: Partial(Types.CreateMessage)) RequestFailedError!Result(Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}", .{ channel_id.into(), message_id.into() }); @@ -1096,7 +1097,7 @@ pub fn editMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, ed /// Get a channel by ID. /// Returns a channel object. /// If the channel is a thread, a thread member object is included in the returned result. -pub fn fetchChannel(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn fetchChannel(self: *Self, channel_id: Snowflake) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}", .{channel_id.into()}); @@ -1110,7 +1111,7 @@ pub fn fetchChannel(self: *Self, channel_id: Snowflake) RequestFailedError!zjson /// Update a channel's settings. /// Returns a channel on success, and a 400 BAD REQUEST on invalid parameters. /// All JSON parameters are optional. -pub fn editChannel(self: *Self, channel_id: Snowflake, edit_channel: Types.ModifyChannel, reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn editChannel(self: *Self, channel_id: Snowflake, edit_channel: Types.ModifyChannel, reason: ?[]const u8) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}", .{channel_id.into()}); @@ -1128,7 +1129,7 @@ pub fn editChannel(self: *Self, channel_id: Snowflake, edit_channel: Types.Modif /// Deleting a category does not delete its child channels; they will have their parent_id removed and a Channel Update Gateway event will fire for each of them. /// Returns a channel object on success. /// Fires a Channel Delete Gateway event (or Thread Delete if the channel was a thread). -pub fn deleteChannel(self: *Self, channel_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn deleteChannel(self: *Self, channel_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}", .{channel_id.into()}); @@ -1137,7 +1138,7 @@ pub fn deleteChannel(self: *Self, channel_id: Snowflake, reason: ?[]const u8) Re try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } pub const ModifyChannelPermissions = struct { @@ -1161,7 +1162,7 @@ pub fn editChannelPermissions( overwrite_id: Snowflake, params: ModifyChannelPermissions, reason: ?[]const u8, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/permissions/{d}", .{ channel_id.into(), overwrite_id.into() }); @@ -1170,13 +1171,13 @@ pub fn editChannelPermissions( try req.addHeader("X-Audit-Log-Reason", reason); - try req.put5(path, params); + return req.put5(path, params); } /// Returns a list of invite objects (with invite metadata) for the channel. /// Only usable for guild channels. /// Requires the `MANAGE_CHANNELS` permission. -pub fn fetchChannelInvites(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Invite) { +pub fn fetchChannelInvites(self: *Self, channel_id: Snowflake) RequestFailedError!Result([]Types.Invite) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/invites", .{channel_id.into()}); @@ -1193,7 +1194,7 @@ pub fn fetchChannelInvites(self: *Self, channel_id: Snowflake) RequestFailedErro /// All JSON parameters for this route are optional, however the request body is not. /// If you are not sending any fields, you still have to send an empty JSON object ({}). /// Returns an invite object. Fires an Invite Create Gateway event. -pub fn createChannelInvite(self: *Self, channel_id: Snowflake, params: Types.CreateChannelInvite, reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.Invite) { +pub fn createChannelInvite(self: *Self, channel_id: Snowflake, params: Types.CreateChannelInvite, reason: ?[]const u8) RequestFailedError!Result(Types.Invite) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/invites", .{channel_id.into()}); @@ -1212,15 +1213,16 @@ pub fn createChannelInvite(self: *Self, channel_id: Snowflake, params: Types.Cre /// Returns a 204 empty response on success. /// Fires a Channel Update Gateway event. /// For more information about permissions, see permissions -/// TODO: add reason headers -pub fn deleteChannelPermission(self: *Self, channel_id: Snowflake, overwrite_id: Snowflake) RequestFailedError!zjson.Owned(Types.Invite) { +pub fn deleteChannelPermission(self: *Self, channel_id: Snowflake, overwrite_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/permissions/{d}", .{ channel_id.into(), overwrite_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + try req.addHeader("X-Audit-Log-Reason", reason); + + return req.delete(path); } /// Follow an Announcement Channel to send messages to a target channel. @@ -1233,7 +1235,7 @@ pub fn followAnnouncementChannel( channel_id: Snowflake, params: Types.FollowAnnouncementChannel, reason: ?[]const u8, -) RequestFailedError!zjson.Owned(Types.FollowedChannel) { +) RequestFailedError!Result(Types.FollowedChannel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/followers", .{channel_id.into()}); @@ -1251,18 +1253,18 @@ pub fn followAnnouncementChannel( /// Fires a Typing Start Gateway event. /// /// Generally bots should not use this route. However, if a bot is responding to a command and expects the computation to take a few seconds, this endpoint may be called to let the user know that the bot is processing their message. -pub fn triggerTypingIndicator(self: *Self, channel_id: Snowflake) RequestFailedError!void { +pub fn triggerTypingIndicator(self: *Self, channel_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/typing", .{channel_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.post4(path); + return req.post4(path); } /// Returns all pinned messages in the channel as an array of message objects. -pub fn fetchPins(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Message) { +pub fn fetchPins(self: *Self, channel_id: Snowflake) RequestFailedError!Result([]Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/pins", .{channel_id.into()}); @@ -1277,7 +1279,7 @@ pub fn fetchPins(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Ow /// Requires the `MANAGE_MESSAGES` permission. /// Returns a 204 empty response on success. /// Fires a Channel Pins Update Gateway event. -pub fn pinMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn pinMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/pins/{d}", .{ channel_id.into(), message_id.into() }); @@ -1286,14 +1288,14 @@ pub fn pinMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, rea try req.addHeader("X-Audit-Log-Reason", reason); - try req.post5(path); + return req.post5(path); } /// Unpin a message in a channel. /// Requires the `MANAGE_MESSAGES` permission. /// Returns a 204 empty response on success. /// Fires a Channel Pins Update Gateway event. -pub fn unpinMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn unpinMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/pins/{d}", .{ channel_id.into(), message_id.into() }); @@ -1302,7 +1304,7 @@ pub fn unpinMessage(self: *Self, channel_id: Snowflake, message_id: Snowflake, r try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } pub fn groupDmAddRecipient() !void { @@ -1327,7 +1329,7 @@ pub fn startThreadFromMessage( message_id: Snowflake, params: Types.StartThreadFromMessage, reason: ?[]const u8, -) RequestFailedError!zjson.Owned(Types.Channel) { +) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/messages/{d}/threads", .{ channel_id.into(), message_id.into() }); @@ -1343,7 +1345,7 @@ pub fn startThreadFromMessage( /// Creates a new thread that is not connected to an existing message. /// Returns a channel on success, and a 400 BAD REQUEST on invalid parameters. /// Fires a Thread Create Gateway event. -pub fn startThread(self: *Self, channel_id: Snowflake, params: Types.StartThreadFromMessage, reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn startThread(self: *Self, channel_id: Snowflake, params: Types.StartThreadFromMessage, reason: ?[]const u8) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/threads", .{channel_id.into()}); @@ -1359,7 +1361,7 @@ pub fn startThread(self: *Self, channel_id: Snowflake, params: Types.StartThread /// Creates a new thread in a forum or a media channel, and sends a message within the created thread. /// Returns a channel, with a nested message object, on success, and a 400 BAD REQUEST on invalid parameters. /// Fires a Thread Create and Message Create Gateway event. -pub fn startThreadInForumOrMediaChannel(self: *Self, channel_id: Snowflake, params: Types.StartThreadFromMessage, reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn startThreadInForumOrMediaChannel(self: *Self, channel_id: Snowflake, params: Types.StartThreadFromMessage, reason: ?[]const u8) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/threads", .{channel_id.into()}); @@ -1384,7 +1386,7 @@ pub fn startThreadInForumOrMediaChannelWithFiles( channel_id: Snowflake, options: StartThreadInForumOrMediaChannelWithFiles, reason: ?[]const u8, -) RequestFailedError!zjson.Owned(Types.Channel) { +) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/threads", .{channel_id.into()}); @@ -1392,7 +1394,6 @@ pub fn startThreadInForumOrMediaChannelWithFiles( defer req.deinit(); try req.addHeader("X-Audit-Log-Reason", reason); - const thread = try req.post3(Types.Channel, path, options.start_thread, options.files); return thread; } @@ -1400,40 +1401,40 @@ pub fn startThreadInForumOrMediaChannelWithFiles( /// Adds the current user to a thread. Also requires the thread is not archived. /// Returns a 204 empty response on success. /// Fires a Thread Members Update and a Thread Create Gateway event. -pub fn joinThread(self: *Self, channel_id: Snowflake) RequestFailedError!void { +pub fn joinThread(self: *Self, channel_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/thread-members/@me", .{channel_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.put3(path); + return req.put3(path); } /// Adds another member to a thread. Requires the ability to send messages in the thread. Also requires the thread is not archived. /// Returns a 204 empty response if the member is successfully added or was already a member of the thread. /// Fires a Thread Members Update Gateway event. -pub fn addMemberToThread(self: *Self, channel_id: Snowflake, user_id: Snowflake) RequestFailedError!void { +pub fn addMemberToThread(self: *Self, channel_id: Snowflake, user_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/thread-members/{d}", .{ channel_id.into(), user_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.put3(path); + return req.put3(path); } /// Removes the current user from a thread. Also requires the thread is not archived. /// Returns a 204 empty response on success. /// Fires a Thread Members Update Gateway event. -pub fn leaveThread(self: *Self, channel_id: Snowflake) RequestFailedError!void { +pub fn leaveThread(self: *Self, channel_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/thread-members/@me", .{channel_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Removes another member from a thread. @@ -1441,14 +1442,14 @@ pub fn leaveThread(self: *Self, channel_id: Snowflake) RequestFailedError!void { /// Also requires the thread is not archived. /// Returns a 204 empty response on success. /// Fires a Thread Members Update Gateway event. -pub fn removeMemberFromThread(self: *Self, channel_id: Snowflake, user_id: Snowflake) RequestFailedError!void { +pub fn removeMemberFromThread(self: *Self, channel_id: Snowflake, user_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/thread-members/{d}", .{ channel_id.into(), user_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Returns a thread member object for the specified user if they are a member of the thread, returns a 404 response otherwise. @@ -1459,7 +1460,7 @@ pub fn fetchThreadMember( channel_id: Snowflake, user_id: Snowflake, with_member: bool, -) RequestFailedError!zjson.Owned(Types.ThreadMember) { +) RequestFailedError!Result(Types.ThreadMember) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/thread-members/{d}?with_member={s}", .{ channel_id.into(), @@ -1481,7 +1482,7 @@ pub fn fetchThreadMember( pub fn fetchThreadMembers( self: *Self, channel_id: Snowflake, -) RequestFailedError!zjson.Owned([]Types.ThreadMember) { +) RequestFailedError!Result([]Types.ThreadMember) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/thread-members/", .{channel_id.into()}); @@ -1498,7 +1499,7 @@ pub fn fetchThreadMembers( /// Threads are ordered by `archive_timestamp`, in descending order. /// Requires the `READ_MESSAGE_HISTORY` permission. /// TODO: implement query string params -pub fn listPublicArchivedThreads(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Owned(Types.ArchivedThreads) { +pub fn listPublicArchivedThreads(self: *Self, channel_id: Snowflake) RequestFailedError!Result(Types.ArchivedThreads) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/threads/archived/public", .{channel_id.into()}); @@ -1513,7 +1514,7 @@ pub fn listPublicArchivedThreads(self: *Self, channel_id: Snowflake) RequestFail /// Threads are ordered by `archive_timestamp`, in descending order. /// Requires both the `READ_MESSAGE_HISTORY` and `MANAGE_THREADS` permissions. /// TODO: implement query string params -pub fn listPrivateArchivedThreads(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Owned(Types.ArchivedThreads) { +pub fn listPrivateArchivedThreads(self: *Self, channel_id: Snowflake) RequestFailedError!Result(Types.ArchivedThreads) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/threads/archived/private", .{channel_id.into()}); @@ -1528,7 +1529,7 @@ pub fn listPrivateArchivedThreads(self: *Self, channel_id: Snowflake) RequestFai /// Threads are ordered by their id, in descending order. /// Requires the `READ_MESSAGE_HISTORY` permission. /// TODO: implement query string params -pub fn listMyPrivateArchivedThreads(self: *Self, channel_id: Snowflake) RequestFailedError!zjson.Owned(Types.ArchivedThreads) { +pub fn listMyPrivateArchivedThreads(self: *Self, channel_id: Snowflake) RequestFailedError!Result(Types.ArchivedThreads) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/users/@me/threads/archived/private", .{channel_id.into()}); @@ -1540,7 +1541,7 @@ pub fn listMyPrivateArchivedThreads(self: *Self, channel_id: Snowflake) RequestF } /// perhaps they abused this endpoint so it remains with no documentation - Yuzu -pub fn createChannel(self: *Self, guild_id: Snowflake, create_channel: Types.CreateGuildChannel) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn createChannel(self: *Self, guild_id: Snowflake, create_channel: Types.CreateGuildChannel) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/channels", .{guild_id.into()}); @@ -1556,7 +1557,7 @@ pub fn createChannel(self: *Self, guild_id: Snowflake, create_channel: Types.Cre /// Method to fetch a guild /// Returns the guild object for the given id. /// If `with_counts` is set to true, this endpoint will also return `approximate_member_count` and `approximate_presence_count` for the guild. -pub fn fetchGuild(self: *Self, guild_id: Snowflake, with_counts: ?bool) RequestFailedError!zjson.Owned(Types.Guild) { +pub fn fetchGuild(self: *Self, guild_id: Snowflake, with_counts: ?bool) RequestFailedError!Result(Types.Guild) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}", .{guild_id.into()}); @@ -1571,7 +1572,7 @@ pub fn fetchGuild(self: *Self, guild_id: Snowflake, with_counts: ?bool) RequestF /// Method to fetch a guild preview /// Returns the guild preview object for the given id. If the user is not in the guild, then the guild must be discoverable. -pub fn fetchGuildPreview(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.GuildPreview) { +pub fn fetchGuildPreview(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.GuildPreview) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/preview", .{guild_id.into()}); @@ -1585,7 +1586,7 @@ pub fn fetchGuildPreview(self: *Self, guild_id: Snowflake) RequestFailedError!zj /// Method to fetch a guild's channels /// Returns a list of guild channel objects. Does not include threads. /// TODO: implement query string parameters -pub fn fetchGuildChannels(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Channel) { +pub fn fetchGuildChannels(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/channels", .{guild_id.into()}); @@ -1601,8 +1602,9 @@ pub fn fetchGuildChannels(self: *Self, guild_id: Snowflake) RequestFailedError!z /// Requires the `MANAGE_CHANNELS` permission. /// If setting permission overwrites, only permissions your bot has in the guild can be allowed/denied. /// Setting `MANAGE_ROLES` permission in channels is only possible for guild administrators. -/// Returns the new channel object on success. Fires a Channel Create Gateway event. -pub fn createGuildChannel(self: *Self, guild_id: Snowflake, create_guild_channel: Types.CreateGuildChannel) RequestFailedError!zjson.Owned(Types.Channel) { +/// Returns the new channel object on success. +/// Fires a Channel Create Gateway event. +pub fn createGuildChannel(self: *Self, guild_id: Snowflake, create_guild_channel: Types.CreateGuildChannel) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/channels", .{guild_id.into()}); @@ -1619,20 +1621,20 @@ pub fn createGuildChannel(self: *Self, guild_id: Snowflake, create_guild_channel /// If setting permission overwrites, only permissions your bot has in the guild can be allowed/denied. /// Setting `MANAGE_ROLES` permission in channels is only possible for guild administrators. /// Returns the new channel object on success. Fires a Channel Create Gateway event. -pub fn editGuildChannelPositions(self: *Self, guild_id: Snowflake, edit_guild_channel: Types.ModifyGuildChannelPositions) RequestFailedError!void { +pub fn editGuildChannelPositions(self: *Self, guild_id: Snowflake, edit_guild_channel: Types.ModifyGuildChannelPositions) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/channels", .{guild_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.patch2(void, path, edit_guild_channel); + return req.patch2(Types.Channel, path, edit_guild_channel); } /// Method to get a guild's active threads /// Returns all active threads in the guild, including public and private threads. /// Threads are ordered by their `id`, in descending order. -pub fn fetchGuildActiveThreads(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn fetchGuildActiveThreads(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.Channel) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/threads/active", .{guild_id.into()}); @@ -1645,7 +1647,7 @@ pub fn fetchGuildActiveThreads(self: *Self, guild_id: Snowflake) RequestFailedEr /// Method to get a member /// Returns a guild member object for the specified user. -pub fn fetchMember(self: *Self, guild_id: Snowflake, user_id: Snowflake) RequestFailedError!zjson.Owned(Types.Member) { +pub fn fetchMember(self: *Self, guild_id: Snowflake, user_id: Snowflake) RequestFailedError!Result(Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}", .{ guild_id.into(), user_id.into() }); @@ -1665,7 +1667,7 @@ pub const ListGuildMembersQuery = struct { /// Method to get the members of a guild /// Returns a list of guild member objects that are members of the guild. -pub fn fetchMembers(self: *Self, guild_id: Snowflake, query: ListGuildMembersQuery) RequestFailedError!zjson.Owned([]Types.Member) { +pub fn fetchMembers(self: *Self, guild_id: Snowflake, query: ListGuildMembersQuery) RequestFailedError!Result([]Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members", .{guild_id.into()}); @@ -1688,7 +1690,7 @@ pub const SearchGuildMembersQuery = struct { /// Method to find members /// Returns a list of guild member objects whose username or nickname starts with a provided string. -pub fn searchMembers(self: *Self, guild_id: Snowflake, query: SearchGuildMembersQuery) RequestFailedError!zjson.Owned([]Types.Member) { +pub fn searchMembers(self: *Self, guild_id: Snowflake, query: SearchGuildMembersQuery) RequestFailedError!Result([]Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/search", .{ guild_id.into(), @@ -1710,7 +1712,7 @@ pub fn searchMembers(self: *Self, guild_id: Snowflake, query: SearchGuildMembers /// /// For guilds with Membership Screening enabled, this endpoint will default to adding new members as pending in the guild member object. /// Members that are pending will have to complete membership screening before they become full members that can talk. -pub fn addMember(self: *Self, guild_id: Snowflake, user_id: Snowflake, credentials: Types.AddGuildMember) RequestFailedError!?zjson.Owned(Types.Member) { +pub fn addMember(self: *Self, guild_id: Snowflake, user_id: Snowflake, credentials: Types.AddGuildMember) RequestFailedError!?Result(Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}", .{ guild_id.into(), user_id.into() }); @@ -1732,7 +1734,7 @@ pub fn editMember( user_id: Snowflake, attributes: Types.ModifyGuildMember, reason: ?[]const u8, -) RequestFailedError!?zjson.Owned(Types.Member) { +) RequestFailedError!?Result(Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}", .{ guild_id.into(), user_id.into() }); @@ -1745,7 +1747,7 @@ pub fn editMember( return res; } -pub fn editCurrentMember(self: *Self, guild_id: Snowflake, attributes: Types.ModifyGuildMember, reason: ?[]const u8) RequestFailedError!?zjson.Owned(Types.Member) { +pub fn editCurrentMember(self: *Self, guild_id: Snowflake, attributes: Types.ModifyGuildMember, reason: ?[]const u8) RequestFailedError!?Result(Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/@me", .{guild_id.into()}); @@ -1759,7 +1761,7 @@ pub fn editCurrentMember(self: *Self, guild_id: Snowflake, attributes: Types.Mod } /// change's someones's nickname -pub fn changeNickname(self: *Self, guild_id: Snowflake, user_id: Snowflake, nick: []const u8, reason: ?[]const u8) RequestFailedError!void { +pub fn changeNickname(self: *Self, guild_id: Snowflake, user_id: Snowflake, nick: []const u8, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}", .{ guild_id.into(), user_id.into() }); @@ -1769,11 +1771,11 @@ pub fn changeNickname(self: *Self, guild_id: Snowflake, user_id: Snowflake, nick try req.addHeader("X-Audit-Log-Reason", reason); const res = try req.patch(Types.Member, path, .{ .nick = nick }); - defer res.deinit(); + return res; } /// change's someones's nickname -pub fn changeMyNickname(self: *Self, guild_id: Snowflake, nick: []const u8, reason: ?[]const u8) RequestFailedError!void { +pub fn changeMyNickname(self: *Self, guild_id: Snowflake, nick: []const u8, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/@me", .{guild_id.into()}); @@ -1783,7 +1785,7 @@ pub fn changeMyNickname(self: *Self, guild_id: Snowflake, nick: []const u8, reas try req.addHeader("X-Audit-Log-Reason", reason); const res = try req.patch(Types.Member, path, .{ .nick = nick }); - defer res.deinit(); + return res; } /// Adds a role to a guild member. Requires the `MANAGE_ROLES` permission. @@ -1795,7 +1797,7 @@ pub fn addRole( user_id: Snowflake, role_id: Snowflake, reason: ?[]const u8, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}/roles/{d}", .{ guild_id.into(), @@ -1808,7 +1810,7 @@ pub fn addRole( try req.addHeader("X-Audit-Log-Reason", reason); - try req.put3(path); + return req.put3(path); } /// Removes a role from a guild member. @@ -1821,7 +1823,7 @@ pub fn removeRole( user_id: Snowflake, role_id: Snowflake, reason: ?[]const u8, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}/roles/{d}", .{ guild_id.into(), @@ -1834,7 +1836,7 @@ pub fn removeRole( try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } /// Remove a member from a guild. @@ -1846,7 +1848,7 @@ pub fn kickMember( guild_id: Snowflake, user_id: Snowflake, reason: ?[]const u8, -) RequestFailedError!void { +) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/members/{d}", .{ guild_id.into(), user_id.into() }); @@ -1855,7 +1857,7 @@ pub fn kickMember( try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } /// Provide a user id to before and after for pagination. @@ -1873,7 +1875,7 @@ pub const GetGuildBansQuery = struct { pub fn fetchBans( self: *Self, guild_id: Snowflake, -) RequestFailedError!zjson.Owned([]Types.Ban) { +) RequestFailedError!Result([]Types.Ban) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/bans", .{guild_id.into()}); @@ -1886,7 +1888,7 @@ pub fn fetchBans( /// Returns a ban object for the given user or a 404 not found if the ban cannot be found. /// Requires the `BAN_MEMBERS` permission. -pub fn fetchBan(self: *Self, guild_id: Snowflake, user_id: Snowflake) RequestFailedError!zjson.Owned(Types.Ban) { +pub fn fetchBan(self: *Self, guild_id: Snowflake, user_id: Snowflake) RequestFailedError!Result(Types.Ban) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/bans/{d}", .{ guild_id.into(), user_id.into() }); @@ -1901,7 +1903,7 @@ pub fn fetchBan(self: *Self, guild_id: Snowflake, user_id: Snowflake) RequestFai /// Requires the `BAN_MEMBERS` permission. /// Returns a 204 empty response on success. /// Fires a Guild Ban Add Gateway event. -pub fn ban(self: *Self, guild_id: Snowflake, user_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn ban(self: *Self, guild_id: Snowflake, user_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/bans/{d}", .{ guild_id.into(), user_id.into() }); @@ -1910,13 +1912,13 @@ pub fn ban(self: *Self, guild_id: Snowflake, user_id: Snowflake, reason: ?[]cons try req.addHeader("X-Audit-Log-Reason", reason); - try req.put3(path); + return req.put3(path); } /// Remove the ban for a user. Requires the `BAN_MEMBERS` permissions. /// Returns a 204 empty response on success. /// Fires a Guild Ban Remove Gateway event. -pub fn unban(self: *Self, guild_id: Snowflake, user_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn unban(self: *Self, guild_id: Snowflake, user_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/bans/{d}", .{ guild_id.into(), user_id.into() }); @@ -1925,14 +1927,14 @@ pub fn unban(self: *Self, guild_id: Snowflake, user_id: Snowflake, reason: ?[]co try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } /// Ban up to 200 users from a guild, and optionally delete previous messages sent by the banned users. /// Requires both the `BAN_MEMBERS` and `MANAGE_GUILD` permissions. /// Returns a 200 response on success, including the fields banned_users with the IDs of the banned users /// and failed_users with IDs that could not be banned or were already banned. -pub fn bulkBan(self: *Self, guild_id: Snowflake, bulk_ban: Types.CreateGuildBan, reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.BulkBan) { +pub fn bulkBan(self: *Self, guild_id: Snowflake, bulk_ban: Types.CreateGuildBan, reason: ?[]const u8) RequestFailedError!Result(Types.BulkBan) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/bulk-ban", .{guild_id.into()}); @@ -1949,21 +1951,21 @@ pub fn bulkBan(self: *Self, guild_id: Snowflake, bulk_ban: Types.CreateGuildBan, /// Delete a guild permanently. User must be owner. /// Returns 204 No Content on success. /// Fires a Guild Delete Gateway event. -pub fn deleteGuild(self: *Self, guild_id: Snowflake) RequestFailedError!void { +pub fn deleteGuild(self: *Self, guild_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}", .{guild_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Method to edit a guild /// Modify a guild's settings. Requires the `MANAGE_GUILD` permission. /// Returns the updated guild object on success. /// Fires a Guild Update Gateway event. -pub fn editGuild(self: *Self, guild_id: Snowflake, edit_guild: Types.ModifyGuild) RequestFailedError!zjson.Owned(Types.Guild) { +pub fn editGuild(self: *Self, guild_id: Snowflake, edit_guild: Types.ModifyGuild) RequestFailedError!Result(Types.Guild) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}", .{guild_id.into()}); @@ -1974,7 +1976,7 @@ pub fn editGuild(self: *Self, guild_id: Snowflake, edit_guild: Types.ModifyGuild return res; } -pub fn createGuild(self: *Self, create_guild: Partial(Types.CreateGuild)) RequestFailedError!zjson.Owned(Types.Guild) { +pub fn createGuild(self: *Self, create_guild: Partial(Types.CreateGuild)) RequestFailedError!Result(Types.Guild) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds", .{}); @@ -1990,7 +1992,7 @@ pub fn createGuild(self: *Self, create_guild: Partial(Types.CreateGuild)) Reques /// Returns the new role object on success. /// Fires a Guild Role Create Gateway event. /// All JSON params are optional. -pub fn createRole(self: *Self, guild_id: Snowflake, create_role: Partial(Types.CreateGuildRole), reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.Role) { +pub fn createRole(self: *Self, guild_id: Snowflake, create_role: Partial(Types.CreateGuildRole), reason: ?[]const u8) RequestFailedError!Result(Types.Role) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/roles", .{guild_id.into()}); @@ -2013,7 +2015,7 @@ pub fn editRole( role_id: Snowflake, edit_role: Partial(Types.ModifyGuildRole), reason: ?[]const u8, -) RequestFailedError!zjson.Owned(Types.Role) { +) RequestFailedError!Result(Types.Role) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/roles/{d}", .{ guild_id.into(), role_id.into() }); @@ -2030,7 +2032,7 @@ pub fn editRole( /// Requires guild ownership. /// Returns the updated level on success. /// Fires a Guild Update Gateway event. -pub fn modifyMFALevel(self: *Self, guild_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn modifyMFALevel(self: *Self, guild_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/mfa", .{guild_id.into()}); @@ -2039,14 +2041,14 @@ pub fn modifyMFALevel(self: *Self, guild_id: Snowflake, reason: ?[]const u8) Req try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(Types.Role, path); + return req.delete(Types.Role, path); } /// Delete a guild role. /// Requires the `MANAGE_ROLES` permission. /// Returns a 204 empty response on success. /// Fires a Guild Role Delete Gateway event. -pub fn deleteRole(self: *Self, guild_id: Snowflake, role_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn deleteRole(self: *Self, guild_id: Snowflake, role_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/roles/{d}", .{ guild_id.into(), role_id.into() }); @@ -2055,7 +2057,7 @@ pub fn deleteRole(self: *Self, guild_id: Snowflake, role_id: Snowflake, reason: try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(Types.Role, path); + return req.delete(Types.Role, path); } /// Returns an object with one pruned key indicating the number of members that would be removed in a prune operation. @@ -2063,7 +2065,7 @@ pub fn deleteRole(self: *Self, guild_id: Snowflake, role_id: Snowflake, reason: /// By default, prune will not remove users with roles. /// You can optionally include specific roles in your prune by providing the include_roles parameter. /// Any inactive user that has a subset of the provided role(s) will be counted in the prune and users with additional roles will not. -pub fn fetchPruneCount(self: *Self, guild_id: Snowflake, query: Types.GetGuildPruneCountQuery) RequestFailedError!zjson.Owned(struct { pruned: isize }) { +pub fn fetchPruneCount(self: *Self, guild_id: Snowflake, query: Types.GetGuildPruneCountQuery) RequestFailedError!Result(struct { pruned: isize }) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/prune", .{guild_id.into()}); @@ -2091,7 +2093,7 @@ pub fn beginGuildPrune( guild_id: Snowflake, params: Types.BeginGuildPrune, reason: ?[]const u8, -) RequestFailedError!zjson.Owned(struct { pruned: isize }) { +) RequestFailedError!Result(struct { pruned: isize }) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/prune", .{guild_id.into()}); @@ -2106,7 +2108,7 @@ pub fn beginGuildPrune( /// Returns a list of voice region objects for the guild. /// Unlike the similar /voice route, this returns VIP servers when the guild is VIP-enabled. -pub fn fetchVoiceRegion(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.VoiceRegion) { +pub fn fetchVoiceRegion(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.VoiceRegion) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/regions", .{guild_id.into()}); @@ -2119,7 +2121,7 @@ pub fn fetchVoiceRegion(self: *Self, guild_id: Snowflake) RequestFailedError!zjs /// Returns a list of invite objects (with invite metadata) for the guild. /// Requires the `MANAGE_GUILD` permission. -pub fn fetchInvites(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Invite) { +pub fn fetchInvites(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.Invite) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/invites", .{guild_id.into()}); @@ -2132,7 +2134,7 @@ pub fn fetchInvites(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.O /// Returns a list of integration objects for the guild. /// Requires the `MANAGE_GUILD` permission. -pub fn fetchIntegrations(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Integration) { +pub fn fetchIntegrations(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.Integration) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/integrations", .{guild_id.into()}); @@ -2145,7 +2147,7 @@ pub fn fetchIntegrations(self: *Self, guild_id: Snowflake) RequestFailedError!zj /// Returns a list of integration objects for the guild. /// Requires the `MANAGE_GUILD` permission. -pub fn deleteIntegration(self: *Self, guild_id: Snowflake, integration_id: Snowflake, reason: ?[]const u8) RequestFailedError!void { +pub fn deleteIntegration(self: *Self, guild_id: Snowflake, integration_id: Snowflake, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/integrations/{d}", .{ guild_id.into(), @@ -2157,12 +2159,12 @@ pub fn deleteIntegration(self: *Self, guild_id: Snowflake, integration_id: Snowf try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } /// Returns a guild widget settings object. /// Requires the `MANAGE_GUILD` permission. -pub fn fetchWidgetSettings(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.GuildWidgetSettings) { +pub fn fetchWidgetSettings(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.GuildWidgetSettings) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/widget", .{guild_id.into()}); @@ -2178,7 +2180,7 @@ pub fn fetchWidgetSettings(self: *Self, guild_id: Snowflake) RequestFailedError! /// Requires the `MANAGE_GUILD` permission. /// Returns the updated guild widget settings object. /// Fires a Guild Update Gateway event. -pub fn editWidget(self: *Self, guild_id: Snowflake, attributes: Partial(Types.GuildWidget), reason: ?[]const u8) RequestFailedError!zjson.Owned(Types.GuildWidget) { +pub fn editWidget(self: *Self, guild_id: Snowflake, attributes: Partial(Types.GuildWidget), reason: ?[]const u8) RequestFailedError!Result(Types.GuildWidget) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/widget", .{guild_id.into()}); @@ -2193,7 +2195,7 @@ pub fn editWidget(self: *Self, guild_id: Snowflake, attributes: Partial(Types.Gu /// Returns the widget for the guild. /// Fires an Invite Create Gateway event when an invite channel is defined and a new Invite is generated. -pub fn fetchWidget(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.GuildWidget) { +pub fn fetchWidget(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.GuildWidget) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/widget.json", .{guild_id.into()}); @@ -2206,7 +2208,7 @@ pub fn fetchWidget(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Ow /// Returns a partial invite object for guilds with that feature enabled. /// Requires the `MANAGE_GUILD` permission. code will be null if a vanity url for the guild is not set. -pub fn fetchVanityUrl(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Partial(Types.Invite)) { +pub fn fetchVanityUrl(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Partial(Types.Invite)) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/vanity-url", .{guild_id.into()}); @@ -2229,7 +2231,7 @@ pub fn fetchWidgetImage(self: *Self, guild_id: Snowflake) RequestFailedError![]c /// Requires the `MANAGE_GUILD` permission. /// Returns the updated Welcome Screen object. May fire a Guild Update Gateway event. /// TODO: add query params -pub fn fetchWelcomeScreen(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.WelcomeScreen) { +pub fn fetchWelcomeScreen(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.WelcomeScreen) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/welcome-screen", .{guild_id.into()}); @@ -2241,7 +2243,7 @@ pub fn fetchWelcomeScreen(self: *Self, guild_id: Snowflake) RequestFailedError!z } /// Returns the Onboarding object for the guild. -pub fn fetchOnboarding(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.GuildOnboarding) { +pub fn fetchOnboarding(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.GuildOnboarding) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/onboarding", .{guild_id.into()}); @@ -2258,7 +2260,7 @@ pub fn editOnboarding( guild_id: Snowflake, onboarding: Types.GuildOnboardingPromptOption, reason: ?[]const u8, -) RequestFailedError!zjson.Owned(Types.GuildOnboarding) { +) RequestFailedError!Result(Types.GuildOnboarding) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/onboarding", .{guild_id.into()}); @@ -2275,7 +2277,7 @@ pub fn editOnboarding( /// Returns the user object of the requester's account. /// For OAuth2, this requires the identify scope, which will return the object without an email, and optionally the email scope, which returns the object with an email if the user has one. -pub fn fetchMyself(self: *Self) RequestFailedError!zjson.Owned(Types.User) { +pub fn fetchMyself(self: *Self) RequestFailedError!Result(Types.User) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2283,7 +2285,7 @@ pub fn fetchMyself(self: *Self) RequestFailedError!zjson.Owned(Types.User) { } /// Returns a user object for a given user ID. -pub fn fetchUser(self: *Self, user_id: Snowflake) RequestFailedError!zjson.Owned(Types.User) { +pub fn fetchUser(self: *Self, user_id: Snowflake) RequestFailedError!Result(Types.User) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/users/{d}", .{user_id.into()}); @@ -2295,7 +2297,7 @@ pub fn fetchUser(self: *Self, user_id: Snowflake) RequestFailedError!zjson.Owned } /// Returns a user object for a given user ID. -pub fn editMyself(self: *Self, params: Types.ModifyCurrentUser) RequestFailedError!zjson.Owned(Types.User) { +pub fn editMyself(self: *Self, params: Types.ModifyCurrentUser) RequestFailedError!Result(Types.User) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2305,7 +2307,7 @@ pub fn editMyself(self: *Self, params: Types.ModifyCurrentUser) RequestFailedErr /// Returns a list of partial guild objects the current user is a member of. /// For OAuth2, requires the guilds scope. -pub fn fetchMyGuilds(self: *Self, params: Types.ModifyCurrentUser) RequestFailedError!zjson.Owned([]Partial(Types.Guild)) { +pub fn fetchMyGuilds(self: *Self, params: Types.ModifyCurrentUser) RequestFailedError!Result([]Partial(Types.Guild)) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2315,7 +2317,7 @@ pub fn fetchMyGuilds(self: *Self, params: Types.ModifyCurrentUser) RequestFailed /// Returns a guild member object for the current user. /// Requires the guilds.members.read OAuth2 scope. -pub fn fetchMyMember(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned(Types.Member) { +pub fn fetchMyMember(self: *Self, guild_id: Snowflake) RequestFailedError!Result(Types.Member) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/users/@me/guilds/{d}/member", .{guild_id.into()}); @@ -2327,19 +2329,19 @@ pub fn fetchMyMember(self: *Self, guild_id: Snowflake) RequestFailedError!zjson. } /// Leave a guild. Returns a 204 empty response on success. Fires a Guild Delete Gateway event and a Guild Member Remove Gateway event. -pub fn leaveGuild(self: *Self, guild_id: Snowflake) RequestFailedError!void { +pub fn leaveGuild(self: *Self, guild_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/users/@me/guilds/{d}", .{guild_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Create a new DM channel with a user. /// Returns a DM channel object (if one already exists, it will be returned instead). -pub fn dm(self: *Self, whom: Snowflake) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn dm(self: *Self, whom: Snowflake) RequestFailedError!Result(Types.Channel) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2350,7 +2352,7 @@ pub fn dm(self: *Self, whom: Snowflake) RequestFailedError!zjson.Owned(Types.Cha /// Returns a DM channel object. /// This endpoint was intended to be used with the now-deprecated GameBridge SDK. /// Fires a Channel Create Gateway event. -pub fn groupDm(self: *Self, access_tokens: [][]const u8, whose: []struct { Snowflake, []const u8 }) RequestFailedError!zjson.Owned(Types.Channel) { +pub fn groupDm(self: *Self, access_tokens: [][]const u8, whose: []struct { Snowflake, []const u8 }) RequestFailedError!Result(Types.Channel) { _ = self; _ = access_tokens; _ = whose; @@ -2358,7 +2360,7 @@ pub fn groupDm(self: *Self, access_tokens: [][]const u8, whose: []struct { Snowf } /// Returns a list of connection objects. Requires the connections OAuth2 scope. -pub fn fetchMyConnections(self: *Self) RequestFailedError!zjson.Owned([]Types.Connection) { +pub fn fetchMyConnections(self: *Self) RequestFailedError!Result([]Types.Connection) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2380,7 +2382,7 @@ pub fn updateMyApplicationConnection(self: *Self) RequestFailedError!void { /// Returns a list of emoji objects for the given guild. /// Includes `user` fields if the bot has the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. -pub fn fetchEmojis(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Emoji) { +pub fn fetchEmojis(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/emojis", .{guild_id.into()}); @@ -2393,7 +2395,7 @@ pub fn fetchEmojis(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Ow /// Returns an emoji object for the given guild and emoji IDs. /// Includes the `user` field if the bot has the `MANAGE_GUILD_EXPRESSIONS` permission, or if the bot created the emoji and has the the `CREATE_GUILD_EXPRESSIONS` permission. -pub fn fetchEmoji(self: *Self, guild_id: Snowflake, emoji_id: Snowflake) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn fetchEmoji(self: *Self, guild_id: Snowflake, emoji_id: Snowflake) RequestFailedError!Result(Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/emojis/{d}", .{ guild_id.into(), emoji_id.into() }); @@ -2408,7 +2410,7 @@ pub fn fetchEmoji(self: *Self, guild_id: Snowflake, emoji_id: Snowflake) Request /// Requires the `CREATE_GUILD_EXPRESSIONS` permission. /// Returns the new emoji object on success. /// Fires a Guild Emojis Update Gateway event. -pub fn createEmoji(self: *Self, guild_id: Snowflake, emoji: Types.CreateGuildEmoji) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn createEmoji(self: *Self, guild_id: Snowflake, emoji: Types.CreateGuildEmoji) RequestFailedError!Result(Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/emojis", .{guild_id.into()}); @@ -2423,7 +2425,7 @@ pub fn createEmoji(self: *Self, guild_id: Snowflake, emoji: Types.CreateGuildEmo /// For other emojis, requires the `MANAGE_GUILD_EXPRESSIONS` permission. /// Returns the updated emoji object on success. /// Fires a Guild Emojis Update Gateway event. -pub fn editEmoji(self: *Self, guild_id: Snowflake, emoji: Types.ModifyGuildEmoji) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn editEmoji(self: *Self, guild_id: Snowflake, emoji: Types.ModifyGuildEmoji) RequestFailedError!Result(Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/emojis", .{guild_id.into()}); @@ -2438,19 +2440,19 @@ pub fn editEmoji(self: *Self, guild_id: Snowflake, emoji: Types.ModifyGuildEmoji /// For other emojis, requires the `MANAGE_GUILD_EXPRESSIONS` permission. /// Returns 204 No Content on success. /// Fires a Guild Emojis Update Gateway event. -pub fn deleteEmoji(self: *Self, guild_id: Snowflake, emoji_id: Snowflake) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn deleteEmoji(self: *Self, guild_id: Snowflake, emoji_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/emojis/{d}", .{ guild_id.into(), emoji_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Returns an object containing a list of emoji objects for the given application under the `items` key. /// Includes a `user` object for the team member that uploaded the emoji from the app's settings, or for the bot user if uploaded using the API. -pub fn fetchApplicationEmojis(self: *Self, application_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Emoji) { +pub fn fetchApplicationEmojis(self: *Self, application_id: Snowflake) RequestFailedError!Result([]Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/emojis", .{application_id.into()}); @@ -2462,7 +2464,7 @@ pub fn fetchApplicationEmojis(self: *Self, application_id: Snowflake) RequestFai } /// Returns an emoji object for the given application and emoji IDs. Includes the user field. -pub fn fetchApplicationEmoji(self: *Self, application_id: Snowflake, emoji_id: Snowflake) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn fetchApplicationEmoji(self: *Self, application_id: Snowflake, emoji_id: Snowflake) RequestFailedError!Result(Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/emojis/{d}", .{ application_id.into(), emoji_id.into() }); @@ -2474,7 +2476,7 @@ pub fn fetchApplicationEmoji(self: *Self, application_id: Snowflake, emoji_id: S } /// Create a new emoji for the application. Returns the new emoji object on success. -pub fn createApplicationEmoji(self: *Self, application_id: Snowflake, emoji: Types.CreateGuildEmoji) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn createApplicationEmoji(self: *Self, application_id: Snowflake, emoji: Types.CreateGuildEmoji) RequestFailedError!Result(Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/emojis", .{application_id.into()}); @@ -2485,7 +2487,7 @@ pub fn createApplicationEmoji(self: *Self, application_id: Snowflake, emoji: Typ } /// Modify the given emoji. Returns the updated emoji object on success. -pub fn editApplicationEmoji(self: *Self, application_id: Snowflake, emoji: Types.ModifyGuildEmoji) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn editApplicationEmoji(self: *Self, application_id: Snowflake, emoji: Types.ModifyGuildEmoji) RequestFailedError!Result(Types.Emoji) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/emojis", .{application_id.into()}); @@ -2496,20 +2498,20 @@ pub fn editApplicationEmoji(self: *Self, application_id: Snowflake, emoji: Types } /// Delete the given emoji. Returns 204 No Content on success. -pub fn deleteApplicationEmoji(self: *Self, application_id: Snowflake, emoji_id: Snowflake) RequestFailedError!zjson.Owned(Types.Emoji) { +pub fn deleteApplicationEmoji(self: *Self, application_id: Snowflake, emoji_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/emojis/{d}", .{ application_id.into(), emoji_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } // start invites /// Returns an invite object for the given code. -pub fn fetchInvite(self: *Self, code: []const u8) RequestFailedError!zjson.Owned(Types.Invite) { +pub fn fetchInvite(self: *Self, code: []const u8) RequestFailedError!Result(Types.Invite) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/invites/{s}", .{code}); @@ -2523,7 +2525,7 @@ pub fn fetchInvite(self: *Self, code: []const u8) RequestFailedError!zjson.Owned /// Requires the `MANAGE_CHANNELS` permission on the channel this invite belongs to, or `MANAGE_GUILD` to remove any invite across the guild. /// Returns an invite object on success. /// Fires an Invite Delete Gateway event. -pub fn deleteInvite(self: *Self, code: []const u8, reason: ?[]const u8) RequestFailedError!void { +pub fn deleteInvite(self: *Self, code: []const u8, reason: ?[]const u8) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/invites/{s}", .{code}); @@ -2532,7 +2534,7 @@ pub fn deleteInvite(self: *Self, code: []const u8, reason: ?[]const u8) RequestF try req.addHeader("X-Audit-Log-Reason", reason); - try req.delete(path); + return req.delete(path); } // poll stuff @@ -2543,7 +2545,7 @@ pub fn fetchAnswerVoters( channel_id: Snowflake, poll_id: Snowflake, answer_id: Snowflake, -) RequestFailedError!zjson.Owner([]Types.User) { +) RequestFailedError!Result([]Types.User) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/polls/{d}/answers/{d}", .{ channel_id.into(), @@ -2567,7 +2569,7 @@ pub fn endPoll( self: *Self, channel_id: Snowflake, poll_id: Snowflake, -) RequestFailedError!zjson.Owned(Types.Message) { +) RequestFailedError!Result(Types.Message) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/channels/{d}/polls/{d}/expire", .{ channel_id.into(), poll_id.into() }); @@ -2579,7 +2581,7 @@ pub fn endPoll( } /// Returns the application object associated with the requesting bot user. -pub fn fetchMyApplication(self: *Self) RequestFailedError!zjson.Owned(Types.Application) { +pub fn fetchMyApplication(self: *Self) RequestFailedError!Result(Types.Application) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2590,7 +2592,7 @@ pub fn fetchMyApplication(self: *Self) RequestFailedError!zjson.Owned(Types.Appl /// Edit properties of the app associated with the requesting bot user. /// Only properties that are passed will be updated. /// Returns the updated application object on success. -pub fn editMyApplication(self: *Self, params: Types.ModifyApplication) RequestFailedError!zjson.Owned(Types.Application) { +pub fn editMyApplication(self: *Self, params: Types.ModifyApplication) RequestFailedError!Result(Types.Application) { var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); @@ -2600,7 +2602,7 @@ pub fn editMyApplication(self: *Self, params: Types.ModifyApplication) RequestFa /// Returns a serialized activity instance, if it exists. /// Useful for preventing unwanted activity sessions. -pub fn fetchActivityInstance(self: *Self, application_id: Snowflake, insance: []const u8) RequestFailedError!zjson.Owned(Types.ActivityInstance) { +pub fn fetchActivityInstance(self: *Self, application_id: Snowflake, insance: []const u8) RequestFailedError!Result(Types.ActivityInstance) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/activity-instances/{s}", .{ application_id.into(), insance }); @@ -2612,7 +2614,7 @@ pub fn fetchActivityInstance(self: *Self, application_id: Snowflake, insance: [] } /// Returns a list of application role connection metadata objects for the given application. -pub fn fetchApplicationRoleConnectionMetadataRecords(self: *Self, application_id: Snowflake) RequestFailedError!zjson.Owned([]Types.ApplicationRoleConnection) { +pub fn fetchApplicationRoleConnectionMetadataRecords(self: *Self, application_id: Snowflake) RequestFailedError!Result([]Types.ApplicationRoleConnection) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/role-connection/metadata", .{application_id.into()}); @@ -2623,7 +2625,7 @@ pub fn fetchApplicationRoleConnectionMetadataRecords(self: *Self, application_id } /// Updates and returns a list of application role connection metadata objects for the given application. -pub fn updateApplicationRoleConnectionMetadataRecords(self: *Self, application_id: Snowflake) RequestFailedError!zjson.Owned([]Types.ApplicationRoleConnection) { +pub fn updateApplicationRoleConnectionMetadataRecords(self: *Self, application_id: Snowflake) RequestFailedError!Result([]Types.ApplicationRoleConnection) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/role-connection/metadata", .{application_id.into()}); @@ -2634,7 +2636,7 @@ pub fn updateApplicationRoleConnectionMetadataRecords(self: *Self, application_i } /// Returns all entitlements for a given app, active and expired. -pub fn fetchEntitlements(self: *Self, application_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Entitlement) { +pub fn fetchEntitlements(self: *Self, application_id: Snowflake) RequestFailedError!Result([]Types.Entitlement) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/entitlements", .{application_id.into()}); @@ -2646,7 +2648,7 @@ pub fn fetchEntitlements(self: *Self, application_id: Snowflake) RequestFailedEr } /// Returns an entitlement. -pub fn fetchEntitlement(self: *Self, application_id: Snowflake, entitlement_id: Snowflake) RequestFailedError!zjson.Owned(Types.Entitlement) { +pub fn fetchEntitlement(self: *Self, application_id: Snowflake, entitlement_id: Snowflake) RequestFailedError!Result(Types.Entitlement) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/entitlements/{d}", .{ application_id.into(), entitlement_id.into() }); @@ -2661,14 +2663,14 @@ pub fn fetchEntitlement(self: *Self, application_id: Snowflake, entitlement_id: /// The entitlement will have consumed: true when using List Entitlements. /// /// Returns a 204 No Content on success. -pub fn consumeEntitlement(self: *Self, application_id: Snowflake, entitlement_id: Snowflake) RequestFailedError!void { +pub fn consumeEntitlement(self: *Self, application_id: Snowflake, entitlement_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/entitlements/{d}/consume", .{ application_id.into(), entitlement_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.post5(path); + return req.post5(path); } /// Creates a test entitlement to a given SKU for a given guild or user. @@ -2681,7 +2683,7 @@ pub fn createTestEntitlement( self: *Self, application_id: Snowflake, params: Types.CreateTestEntitlement, -) RequestFailedError!zjson.Owned(Partial(Types.Entitlement)) { +) RequestFailedError!Result(Partial(Types.Entitlement)) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/entitlements", .{application_id.into()}); @@ -2694,14 +2696,14 @@ pub fn createTestEntitlement( /// Deletes a currently-active test entitlement. Discord will act as though that user or guild no longer has entitlement to your premium offering. /// /// Returns 204 No Content on success. -pub fn deleteTestEntitlement(self: *Self, application_id: Snowflake) RequestFailedError!void { +pub fn deleteTestEntitlement(self: *Self, application_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/applications/{d}/entitlements", .{application_id.into()}); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } /// Returns all SKUs for a given application. @@ -2719,7 +2721,7 @@ pub fn fetchSkus(self: *Self, application_id: Snowflake) RequestFailedError!zjso // start sticker methods /// Returns a list of available sticker packs. -pub fn fetchStickerPacks(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.StickerPack) { +pub fn fetchStickerPacks(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.StickerPack) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/sticker-packs", .{guild_id.into()}); @@ -2731,7 +2733,7 @@ pub fn fetchStickerPacks(self: *Self, guild_id: Snowflake) RequestFailedError!zj } /// Returns a sticker object for the given sticker ID. -pub fn fetchSticker(self: *Self, sticker_id: Snowflake) RequestFailedError!zjson.Owned(Types.Sticker) { +pub fn fetchSticker(self: *Self, sticker_id: Snowflake) RequestFailedError!Result(Types.Sticker) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/stickers/{d}", .{sticker_id.into()}); @@ -2743,7 +2745,7 @@ pub fn fetchSticker(self: *Self, sticker_id: Snowflake) RequestFailedError!zjson } /// Returns a sticker object for the given sticker ID. -pub fn fetchStickerPack(self: *Self, pack_id: Snowflake) RequestFailedError!zjson.Owned(Types.StickerPack) { +pub fn fetchStickerPack(self: *Self, pack_id: Snowflake) RequestFailedError!Result(Types.StickerPack) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/sticker-packs/{d}", .{pack_id.into()}); @@ -2756,7 +2758,7 @@ pub fn fetchStickerPack(self: *Self, pack_id: Snowflake) RequestFailedError!zjso /// Returns an array of sticker objects for the given guild. /// Includes `user` fields if the bot has the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. -pub fn fetchGuildStickers(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.Sticker) { +pub fn fetchGuildStickers(self: *Self, guild_id: Snowflake) RequestFailedError!Result([]Types.Sticker) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers", .{guild_id.into()}); @@ -2769,7 +2771,7 @@ pub fn fetchGuildStickers(self: *Self, guild_id: Snowflake) RequestFailedError!z /// Returns an array of sticker objects for the given guild. /// Includes `user` fields if the bot has the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. -pub fn fetchGuildSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake) RequestFailedError!zjson.Owned(Types.Sticker) { +pub fn fetchGuildSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake) RequestFailedError!Result(Types.Sticker) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers/{d}", .{ guild_id.into(), sticker_id.into() }); @@ -2789,7 +2791,7 @@ pub fn createSticker( guild_id: Snowflake, sticker: Types.CreateModifyGuildSticker, file: @import("http.zig").FileData, -) RequestFailedError!zjson.Owned(Types.Sticker) { +) RequestFailedError!Result(Types.Sticker) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers", .{guild_id.into()}); @@ -2810,7 +2812,7 @@ pub fn createSticker( /// For other stickers, requires the `MANAGE_GUILD_EXPRESSIONS` permission. /// Returns the updated sticker object on success. /// Fires a Guild Stickers Update Gateway event. -pub fn editSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake, sticker: Types.CreateModifyGuildSticker) RequestFailedError!zjson.Owned(Types.Sticker) { +pub fn editSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake, sticker: Types.CreateModifyGuildSticker) RequestFailedError!Result(Types.Sticker) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers/{d}", .{ guild_id.into(), sticker_id.into() }); @@ -2825,12 +2827,12 @@ pub fn editSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake, stic /// For other stickers, requires the `MANAGE_GUILD_EXPRESSIONS` permission. /// Returns 204 No Content on success. /// Fires a Guild Stickers Update Gateway event. -pub fn deleteSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake) RequestFailedError!void { +pub fn deleteSticker(self: *Self, guild_id: Snowflake, sticker_id: Snowflake) RequestFailedError!Result(void) { var buf: [256]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers/{d}", .{ guild_id.into(), sticker_id.into() }); var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.delete(path); + return req.delete(path); } diff --git a/src/test.zig b/test/test.zig similarity index 81% rename from src/test.zig rename to test/test.zig index cea70cb..03c9768 100644 --- a/src/test.zig +++ b/test/test.zig @@ -14,14 +14,10 @@ //! OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR //! PERFORMANCE OF THIS SOFTWARE. +const std = @import("std"); const Discord = @import("discord.zig"); const Shard = Discord.Shard; -const Internal = Discord.Internal; -const FetchReq = Discord.FetchReq; const Intents = Discord.Intents; -const Thread = std.Thread; -const std = @import("std"); -const fmt = std.fmt; const INTENTS = 53608447; @@ -30,13 +26,14 @@ fn ready(_: *Shard, payload: Discord.Ready) !void { } fn message_create(session: *Shard, message: Discord.Message) !void { - std.debug.print("captured: {?s} send by {s}\n", .{ message.content, message.author.username }); - if (message.content) |mc| if (std.ascii.eqlIgnoreCase(mc, "!hi")) { - const msg = try session.sendMessage(message.channel_id, .{ - .content = "discord.zig best library", - }); - defer msg.deinit(); + var result = try session.sendMessage(message.channel_id, .{ .content = "hi :)" }); + defer result.deinit(); + + switch (result.value) { + .left => |e| std.debug.panic("Error: {d}\r{s}\n", .{ e.code, e.message }), + .right => |m| std.debug.print("Sent: {?s} sent by {s}\n", .{ m.content, m.author.username }), + } }; }