From 3ef516bfa169dc8eb77821927b544a705d4a5b99 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Mon, 9 Dec 2024 17:25:16 -0500 Subject: [PATCH] minor adjustments --- README.md | 1 - build.zig | 8 --- src/http.zig | 7 +- {vendor/zjson => src}/json.zig | 50 +++++++++++++ src/shard.zig | 124 ++++++++++++++++++++++++++++++++- src/structures/application.zig | 5 +- src/structures/events.zig | 2 +- src/structures/guild.zig | 2 +- src/structures/interaction.zig | 2 +- src/structures/message.zig | 59 +--------------- src/structures/shared.zig | 2 +- src/structures/snowflake.zig | 2 +- src/structures/sticker.zig | 67 ++++++++++++++++++ src/structures/types.zig | 1 + src/structures/user.zig | 4 +- src/structures/webhook.zig | 1 - vendor/zjson/README.md | 58 --------------- vendor/zjson/build.zig | 11 --- vendor/zjson/build.zig.zon | 72 ------------------- 19 files changed, 256 insertions(+), 222 deletions(-) rename {vendor/zjson => src}/json.zig (96%) create mode 100644 src/structures/sticker.zig delete mode 100644 vendor/zjson/README.md delete mode 100644 vendor/zjson/build.zig delete mode 100644 vendor/zjson/build.zig.zon diff --git a/README.md b/README.md index 52d64b0..68b6866 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,6 @@ Contributions are welcome! Please open an issue or pull request if you'd like to | Guild template related | ❌ | | Soundboard related | ❌ | | Stage Instance related | ❌ | -| Sticker related | ❌ | | Subscription related | ❌ | | Voice related | ❌ | | Webhook related | ❌ | diff --git a/build.zig b/build.zig index 6ae04dd..a861601 100644 --- a/build.zig +++ b/build.zig @@ -27,12 +27,6 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); - const json_parse = b.addModule("zjson", .{ - .target = target, - .optimize = optimize, - .root_source_file = b.path("vendor/zjson/json.zig"), - }); - const marin = b.addExecutable(.{ .name = "marin", .root_source_file = b.path("src/test.zig"), @@ -46,13 +40,11 @@ pub fn build(b: *std.Build) void { dzig.addImport("ws", websocket.module("websocket")); dzig.addImport("zlib", zlib.module("zlib")); dzig.addImport("deque", deque.module("zig-deque")); - dzig.addImport("json", json_parse); marin.root_module.addImport("discord.zig", dzig); marin.root_module.addImport("ws", websocket.module("websocket")); marin.root_module.addImport("zlib", zlib.module("zlib")); marin.root_module.addImport("deque", deque.module("zig-deque")); - marin.root_module.addImport("json", json_parse); //b.installArtifact(marin); diff --git a/src/http.zig b/src/http.zig index 45bf4b2..2c3f87e 100644 --- a/src/http.zig +++ b/src/http.zig @@ -18,7 +18,7 @@ const std = @import("std"); const mem = std.mem; const http = std.http; const json = std.json; -const zjson = @import("json"); +const zjson = @import("json.zig"); pub const BASE_URL = "https://discord.com/api/v10"; @@ -213,7 +213,7 @@ pub const FetchReq = struct { path: []const u8, object: anytype, files: []const FileData, - ) !void { + ) !zjson.Owned(T) { var buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var string = std.ArrayList(u8).init(fba.allocator()); @@ -222,9 +222,10 @@ pub const FetchReq = struct { try json.stringify(object, .{}, string.writer()); const result = try self.makeRequestWithFiles(.POST, path, try string.toOwnedSlice(), files); - _ = T; if (result.status != .ok) return error.FailedRequest; + + return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice()); } pub fn post4(self: *FetchReq, path: []const u8, object: anytype) !void { diff --git a/vendor/zjson/json.zig b/src/json.zig similarity index 96% rename from vendor/zjson/json.zig rename to src/json.zig index 6c3f29e..d62ac41 100644 --- a/vendor/zjson/json.zig +++ b/src/json.zig @@ -30,6 +30,7 @@ //! defer allocator.deinit(); //! const result = parseIntoT(MyStruct, "{ \"key\": \"value\" }", allocator); //! ``` +//! repo: https://codeberg.org/yuzu/json const std = @import("std"); const mem = std.mem; @@ -1154,3 +1155,52 @@ pub fn Record(comptime T: type) type { } }; } + +/// a hashmap for key value pairs +/// where every key is an int +/// +/// an example would be this +/// +/// { +/// ... +/// "integration_types_config": { +/// "0": ... +/// "1": { +/// "oauth2_install_params": { +/// "scopes": ["applications.commands"], +/// "permissions": "0" +/// } +/// } +/// }, +/// ... +/// } +/// this would help us map an enum member 0, 1, etc of type E into V +/// very useful stuff +/// internally, an EnumMap +pub fn AssociativeArray(comptime E: type, comptime V: type) type { + if (@typeInfo(E) != .@"enum") + @compileError("may only use enums as keys"); + + return struct { + map: std.EnumMap(E, V), + pub fn toJson(allocator: mem.Allocator, value: JsonType) !@This() { + // TODO: initialize this more efficiently + var map = std.EnumMap(E, V){}; + + var iterator = value.object.iterator(); + + while (iterator.next()) |pair| { + const k = pair.key_ptr.*; + const v = pair.value_ptr.*; + + errdefer allocator.free(k); + errdefer v.deinit(allocator); + + const int = std.fmt.parseInt(@typeInfo(E).@"enum".tag_type, k, 10) catch unreachable; + map.put(@enumFromInt(int), try parseInto(V, allocator, v)); + } + + return .{ .map = map }; + } + }; +} diff --git a/src/shard.zig b/src/shard.zig index 3da0ece..8094066 100644 --- a/src/shard.zig +++ b/src/shard.zig @@ -26,7 +26,7 @@ const http = std.http; // todo use this to read compressed messages const zlib = @import("zlib"); -const zjson = @import("json"); +const zjson = @import("json.zig"); const Self = @This(); @@ -901,7 +901,8 @@ pub fn sendMessageWithFiles( var req = FetchReq.init(self.allocator, self.details.token); defer req.deinit(); - try req.post3(Types.Message, path, wf.create_message, wf.files); + const msg = try req.post3(Types.Message, path, wf.create_message, wf.files); + return msg; } /// Crosspost a message in an Announcement Channel to following channels. @@ -2581,3 +2582,122 @@ pub fn fetchSkus(self: *Self, application_id: Snowflake) RequestFailedError!zjso const skus = try req.get([]Types.Sku, path); return skus; } + +// start sticker methods + +/// Returns a list of available sticker packs. +pub fn fetchStickerPacks(self: *Self, guild_id: Snowflake) RequestFailedError!zjson.Owned([]Types.StickerPack) { + var buf: [256]u8 = undefined; + const path = try std.fmt.bufPrint(&buf, "/sticker-packs", .{guild_id.into()}); + + var req = FetchReq.init(self.allocator, self.details.token); + defer req.deinit(); + + const packs = try req.get([]Types.StickerPack, path); + return packs; +} + +/// Returns a sticker object for the given sticker ID. +pub fn fetchSticker(self: *Self, sticker_id: Snowflake) RequestFailedError!zjson.Owned(Types.Sticker) { + var buf: [256]u8 = undefined; + const path = try std.fmt.bufPrint(&buf, "/stickers/{d}", .{sticker_id.into()}); + + var req = FetchReq.init(self.allocator, self.details.token); + defer req.deinit(); + + const sticker = try req.get(Types.Sticker, path); + return sticker; +} + +/// Returns a sticker object for the given sticker ID. +pub fn fetchStickerPack(self: *Self, pack_id: Snowflake) RequestFailedError!zjson.Owned(Types.StickerPack) { + var buf: [256]u8 = undefined; + const path = try std.fmt.bufPrint(&buf, "/sticker-packs/{d}", .{pack_id.into()}); + + var req = FetchReq.init(self.allocator, self.details.token); + defer req.deinit(); + + const pack = try req.get(Types.StickerPack, path); + return pack; +} + +/// 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) { + var buf: [256]u8 = undefined; + const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers", .{guild_id.into()}); + + var req = FetchReq.init(self.allocator, self.details.token); + defer req.deinit(); + + const stickers = try req.get([]Types.Sticker, path); + return stickers; +} + +/// 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) { + 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(); + + const sticker = try req.get(Types.Sticker, path); + return sticker; +} + +/// Create a new sticker for the guild. +/// Requires the `CREATE_GUILD_EXPRESSIONS` permission. +/// Returns the new sticker object on success. +/// Fires a Guild Stickers Update Gateway event. +pub fn createSticker( + self: *Self, + guild_id: Snowflake, + sticker: Types.CreateModifyGuildSticker, + file: @import("http.zig").FileData, +) RequestFailedError!zjson.Owned(Types.Sticker) { + var buf: [256]u8 = undefined; + const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers", .{guild_id.into()}); + + var req = FetchReq.init(self.allocator, self.details.token); + defer req.deinit(); + + var files = .{file}; + return req.post2( + Types.Sticker, + path, + sticker, + &files, + ); +} + +/// Modify the given sticker. +/// For stickers created by the current user, requires either the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. +/// 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) { + 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(); + + return req.patch(Types.Sticker, path, sticker); +} + +/// Delete the given sticker. +/// For stickers created by the current user, requires either the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. +/// 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 { + 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); +} diff --git a/src/structures/application.zig b/src/structures/application.zig index 77bbea2..56f542b 100644 --- a/src/structures/application.zig +++ b/src/structures/application.zig @@ -21,6 +21,7 @@ const Partial = @import("partial.zig").Partial; const User = @import("user.zig").User; const Team = @import("team.zig").Team; const Guild = @import("guild.zig").Guild; +const AssociativeArray = @import("../json.zig").AssociativeArray; /// https://discord.com/developers/docs/resources/application#application-object pub const Application = struct { @@ -65,9 +66,7 @@ pub const Application = struct { /// settings for the application's default in-app authorization link, if enabled install_params: ?InstallParams, // Default scopes and permissions for each supported installation context. - // partial? - // integration_types_config: ?Record(ApplicationIntegrationType, ApplicationIntegrationTypeConfiguration), - + integration_types_config: ?AssociativeArray(ApplicationIntegrationType, ApplicationIntegrationTypeConfiguration), /// the application's default custom authorization link, if enabled custom_install_url: ?[]const u8, /// the application's role connection verification entry point, which when configured will render the app as a verification method in the guild role verification configuration diff --git a/src/structures/events.zig b/src/structures/events.zig index f30cf93..763f6b8 100644 --- a/src/structures/events.zig +++ b/src/structures/events.zig @@ -36,7 +36,7 @@ const Embed = @import("embed.zig").Embed; const WelcomeScreenChannel = @import("channel.zig").WelcomeScreenChannel; const AllowedMentions = @import("channel.zig").AllowedMentions; const MessageComponent = @import("message.zig").MessageComponent; -const Sticker = @import("message.zig").Sticker; +const Sticker = @import("sticker.zig").Sticker; const Partial = @import("partial.zig").Partial; const ReactionType = @import("message.zig").ReactionType; const Team = @import("team.zig").Team; diff --git a/src/structures/guild.zig b/src/structures/guild.zig index bf161be..1d8ba32 100644 --- a/src/structures/guild.zig +++ b/src/structures/guild.zig @@ -28,7 +28,7 @@ const MfaLevels = @import("shared.zig").MfaLevels; const SystemChannelFlags = @import("shared.zig").SystemChannelFlags; const PremiumTiers = @import("shared.zig").PremiumTiers; const Emoji = @import("emoji.zig").Emoji; -const Sticker = @import("message.zig").Sticker; +const Sticker = @import("sticker.zig").Sticker; const Partial = @import("partial.zig").Partial; const PresenceUpdate = @import("gateway.zig").PresenceUpdate; const WelcomeScreen = @import("channel.zig").WelcomeScreen; diff --git a/src/structures/interaction.zig b/src/structures/interaction.zig index 1aa181e..46a2525 100644 --- a/src/structures/interaction.zig +++ b/src/structures/interaction.zig @@ -32,7 +32,7 @@ const ApplicationCommandTypes = @import("shared.zig").ApplicationCommandTypes; const InteractionResponseTypes = @import("shared.zig").InteractionResponseTypes; const InteractionContextType = @import("command.zig").InteractionContextType; const Entitlement = @import("monetization.zig").Entitlement; -const Record = @import("json").Record; +const Record = @import("../json.zig").Record; pub const Interaction = struct { /// Id of the interaction diff --git a/src/structures/message.zig b/src/structures/message.zig index b6daaf1..842bbb0 100644 --- a/src/structures/message.zig +++ b/src/structures/message.zig @@ -23,9 +23,10 @@ const Embed = @import("embed.zig").Embed; const AllowedMentionTypes = @import("shared.zig").AllowedMentionsTypes; const PremiumTypes = @import("shared.zig").PremiumTypes; const InteractionTypes = @import("shared.zig").InteractionTypes; -const StickerTypes = @import("shared.zig").StickerTypes; -const StickerFormatTypes = @import("shared.zig").StickerFormatTypes; const MessageTypes = @import("shared.zig").MessageTypes; +const Sticker = @import("sticker.zig").Sticker; +const StickerItem = @import("sticker.zig").StickerItem; +const StickerPath = @import("sticker.zig").StickerPack; const MessageFlags = @import("shared.zig").MessageFlags; const Emoji = @import("emoji.zig").Emoji; const Poll = @import("poll.zig").Poll; @@ -273,32 +274,6 @@ pub const MessageSnapshot = struct { }, }; -/// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-structure -pub const Sticker = struct { - /// [Id of the sticker](https://discord.com/developers/docs/reference#image-formatting) - id: Snowflake, - /// Id of the pack the sticker is from - pack_id: ?Snowflake, - /// Name of the sticker - name: []const u8, - /// Description of the sticker - description: []const u8, - /// a unicode emoji representing the sticker's expression - tags: []const u8, - /// [type of sticker](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types) - type: StickerTypes, - /// [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) - format_type: StickerFormatTypes, - /// Whether or not the sticker is available - available: ?bool, - /// Id of the guild that owns this sticker - guild_id: ?Snowflake, - /// The user that uploaded the sticker - user: ?User, - /// A sticker's sort order within a pack - sort_value: ?isize, -}; - /// https://discord.com/developers/docs/interactions/receiving-and-responding#message-interaction-object-message-interaction-structure pub const MessageInteraction = struct { /// Id of the interaction @@ -332,34 +307,6 @@ pub const MessageInteractionMetadata = struct { triggering_interaction_metadata: ?*MessageInteractionMetadata, }; -/// https://discord.com/developers/docs/resources/sticker#sticker-item-object-sticker-item-structure -pub const StickerItem = struct { - /// Id of the sticker - id: Snowflake, - /// Name of the sticker - name: []const u8, - /// [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) - format_type: StickerFormatTypes, -}; - -/// https://discord.com/developers/docs/resources/sticker#sticker-pack-object-sticker-pack-structure -pub const StickerPack = struct { - /// id of the sticker pack - id: Snowflake, - /// the stickers in the pack - stickers: []Sticker, - /// name of the sticker pack - name: []const u8, - /// id of the pack's SKU - sku_id: Snowflake, - /// id of a sticker in the pack which is shown as the pack's icon - cover_sticker_id: ?Snowflake, - /// description of the sticker pack - description: []const u8, - /// id of the sticker pack's [banner image](https://discord.com/developers/docs/reference#image-formatting) - banner_asset_id: ?Snowflake, -}; - pub const AllowedMentions = struct { /// An array of allowed mention types to parse from the content. parse: []AllowedMentionTypes, diff --git a/src/structures/shared.zig b/src/structures/shared.zig index 21c84c9..ade0a63 100644 --- a/src/structures/shared.zig +++ b/src/structures/shared.zig @@ -16,7 +16,7 @@ const std = @import("std"); const Snowflake = @import("snowflake.zig").Snowflake; -const zjson = @import("json"); +const zjson = @import("../json.zig"); pub const PresenceStatus = enum { online, diff --git a/src/structures/snowflake.zig b/src/structures/snowflake.zig index d8cfc08..912cd28 100644 --- a/src/structures/snowflake.zig +++ b/src/structures/snowflake.zig @@ -15,7 +15,7 @@ //! PERFORMANCE OF THIS SOFTWARE. const std = @import("std"); -const zjson = @import("json"); +const zjson = @import("../json.zig"); pub const Snowflake = enum(u64) { _, diff --git a/src/structures/sticker.zig b/src/structures/sticker.zig new file mode 100644 index 0000000..b6b0d1e --- /dev/null +++ b/src/structures/sticker.zig @@ -0,0 +1,67 @@ +const Snowflake = @import("snowflake.zig").Snowflake; +const User = @import("user.zig").User; +const StickerTypes = @import("shared.zig").StickerTypes; +const StickerFormatTypes = @import("shared.zig").StickerFormatTypes; + +/// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-structure +pub const Sticker = struct { + /// [Id of the sticker](https://discord.com/developers/docs/reference#image-formatting) + id: Snowflake, + /// Id of the pack the sticker is from + pack_id: ?Snowflake, + /// Name of the sticker + name: []const u8, + /// Description of the sticker + description: []const u8, + /// a unicode emoji representing the sticker's expression + tags: []const u8, + /// [type of sticker](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types) + type: StickerTypes, + /// [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) + format_type: StickerFormatTypes, + /// Whether or not the sticker is available + available: ?bool, + /// Id of the guild that owns this sticker + guild_id: ?Snowflake, + /// The user that uploaded the sticker + user: ?User, + /// A sticker's sort order within a pack + sort_value: ?isize, +}; + +/// https://discord.com/developers/docs/resources/sticker#sticker-item-object-sticker-item-structure +pub const StickerItem = struct { + /// Id of the sticker + id: Snowflake, + /// Name of the sticker + name: []const u8, + /// [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) + format_type: StickerFormatTypes, +}; + +/// https://discord.com/developers/docs/resources/sticker#sticker-pack-object-sticker-pack-structure +pub const StickerPack = struct { + /// id of the sticker pack + id: Snowflake, + /// the stickers in the pack + stickers: []Sticker, + /// name of the sticker pack + name: []const u8, + /// id of the pack's SKU + sku_id: Snowflake, + /// id of a sticker in the pack which is shown as the pack's icon + cover_sticker_id: ?Snowflake, + /// description of the sticker pack + description: []const u8, + /// id of the sticker pack's [banner image](https://discord.com/developers/docs/reference#image-formatting) + banner_asset_id: ?Snowflake, +}; + +pub const CreateModifyGuildSticker = struct { + /// name of the sticker (2-30 characters) + name: ?[]const u8, + /// description of the sticker (2-100 characters) + description: ?[]const u8, + /// autocomplete/suggestion tags for the sticker (max 200 characters) + tags: ?[]const u8, +}; diff --git a/src/structures/types.zig b/src/structures/types.zig index f9485cd..3ef4781 100644 --- a/src/structures/types.zig +++ b/src/structures/types.zig @@ -41,6 +41,7 @@ pub usingnamespace @import("oauth.zig"); pub usingnamespace @import("poll.zig"); pub usingnamespace @import("role.zig"); pub usingnamespace @import("scheduled_event.zig"); +pub usingnamespace @import("sticker.zig"); pub usingnamespace @import("team.zig"); pub usingnamespace @import("thread.zig"); pub usingnamespace @import("user.zig"); diff --git a/src/structures/user.zig b/src/structures/user.zig index e17a664..369d737 100644 --- a/src/structures/user.zig +++ b/src/structures/user.zig @@ -17,10 +17,10 @@ const PremiumTypes = @import("shared.zig").PremiumTypes; const Snowflake = @import("snowflake.zig").Snowflake; const Application = @import("application.zig").Application; -const Record = @import("json").Record; const OAuth2Scope = @import("shared.zig").OAuth2Scope; const Integration = @import("integration.zig").Integration; const Partial = @import("partial.zig").Partial; +const Record = @import("../json.zig").Record; /// https://discord.com/developers/docs/resources/user#user-object pub const User = struct { @@ -115,7 +115,7 @@ pub const Connection = struct { }; /// https://discord.com/developers/docs/resources/user#connection-object-services -pub const ConnectionServiceType = enum { +pub const ConnectionServiceType = union(enum) { @"amazon-music", battlenet, @"Bungie.net", diff --git a/src/structures/webhook.zig b/src/structures/webhook.zig index 8f1f93d..2ba325f 100644 --- a/src/structures/webhook.zig +++ b/src/structures/webhook.zig @@ -68,7 +68,6 @@ pub const ApplicationWebhook = struct { token: ?[]const u8, /// The url used for executing the webhook (returned by the webhooks OAuth2 flow) url: ?[]const u8, - /// The id of the webhook id: Snowflake, /// The guild id this webhook is for diff --git a/vendor/zjson/README.md b/vendor/zjson/README.md deleted file mode 100644 index 4054d04..0000000 --- a/vendor/zjson/README.md +++ /dev/null @@ -1,58 +0,0 @@ -## zjson - -basic usage -```zig -const json = @import("zjson"); - -const data: []const u8 = - \\ { - \\ "username": "yuzu", - \\ "id": 10000, - \\ "bot": true - \\ } -; - -const User = struct { - username: []const u8, - id: u64, - bot: bool, -}; - -const my_user = try json.parse(User, std.testing.allocator, data); -defer my_user.deinit(); - -try std.testing.expectEqual(10000, my_user.value.id); -try std.testing.expectEqualStrings("yuzu", my_user.value.username); -try std.testing.expect(my_user.bot); -``` - -definition of your custom parsing as follows -you can define your own to tell the parser how to behave -```zig -/// this is named after the TypeScript `Record` -pub fn Record(comptime T: type) type { - return struct { - /// the actual data - map: std.StringHashMapUnmanaged(T), - - /// any function `toJson` has this signature - pub fn toJson(allocator: mem.Allocator, value: JsonType) !@This() { - var map: std.StringHashMapUnmanaged(T) = .{}; - - var iterator = value.object.iterator(); - - while (iterator.next()) |pair| { - const k = pair.key_ptr.*; - const v = pair.value_ptr.*; - - // make sure to delete this as placing might fail - errdefer allocator.free(k); - errdefer v.deinit(allocator); - try map.put(allocator, k, try parseInto(T, allocator, v)); - } - - return .{ .map = map }; - } - }; -} -``` diff --git a/vendor/zjson/build.zig b/vendor/zjson/build.zig deleted file mode 100644 index fba79f7..0000000 --- a/vendor/zjson/build.zig +++ /dev/null @@ -1,11 +0,0 @@ -const std = @import("std"); -pub fn build(b: *std.Build) void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - - _ = b.addModule("zjson", .{ - .root_source_file = b.path("json.zig"), - .optimize = optimize, - .target = target, - }); -} diff --git a/vendor/zjson/build.zig.zon b/vendor/zjson/build.zig.zon deleted file mode 100644 index f98cc0c..0000000 --- a/vendor/zjson/build.zig.zon +++ /dev/null @@ -1,72 +0,0 @@ -.{ - // This is the default name used by packages depending on this one. For - // example, when a user runs `zig fetch --save `, this field is used - // as the key in the `dependencies` table. Although the user can choose a - // different name, most users will stick with this provided value. - // - // It is redundant to include "zig" in this name because it is already - // within the Zig package namespace. - .name = "zjson", - - // This is a [Semantic Version](https://semver.org/). - // In a future version of Zig it will be used for package deduplication. - .version = "1.2.0", - - // This field is optional. - // This is currently advisory only; Zig does not yet do anything - // with this value. - //.minimum_zig_version = "0.11.0", - - // This field is optional. - // Each dependency must either provide a `url` and `hash`, or a `path`. - // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. - // Once all dependencies are fetched, `zig build` no longer requires - // internet connectivity. - .dependencies = .{ - // See `zig fetch --save ` for a command-line interface for adding dependencies. - //.example = .{ - // // When updating this field to a new URL, be sure to delete the corresponding - // // `hash`, otherwise you are communicating that you expect to find the old hash at - // // the new URL. - // .url = "https://example.com/foo.tar.gz", - // - // // This is computed from the file contents of the directory of files that is - // // obtained after fetching `url` and applying the inclusion rules given by - // // `paths`. - // // - // // This field is the source of truth; packages do not come from a `url`; they - // // come from a `hash`. `url` is just one of many possible mirrors for how to - // // obtain a package matching this `hash`. - // // - // // Uses the [multihash](https://multiformats.io/multihash/) format. - // .hash = "...", - // - // // When this is provided, the package is found in a directory relative to the - // // build root. In this case the package's hash is irrelevant and therefore not - // // computed. This field and `url` are mutually exclusive. - // .path = "foo", - // - // // When this is set to `true`, a package is declared to be lazily - // // fetched. This makes the dependency only get fetched if it is - // // actually used. - // .lazy = false, - //}, - }, - - // Specifies the set of files and directories that are included in this package. - // Only files and directories listed here are included in the `hash` that - // is computed for this package. Only files listed here will remain on disk - // when using the zig package manager. As a rule of thumb, one should list - // files required for compilation plus any license(s). - // Paths are relative to the build root. Use the empty string (`""`) to refer to - // the build root itself. - // A directory listed here means that all files within, recursively, are included. - .paths = .{ - "build.zig", - "build.zig.zon", - "json.zig", - // For example... - //"LICENSE", - //"README.md", - }, -}