discord.zig/src/parser.zig
2024-11-04 15:46:42 -05:00

123 lines
5.2 KiB
Zig

const zmpl = @import("zmpl");
const Discord = @import("raw_types.zig");
const std = @import("std");
pub fn parseUser(obj: *zmpl.Data.Object) Discord.User {
const avatar_decoration_data_obj = obj.getT(.object, "avatar_decoration_data");
const user = Discord.User{
.clan = null,
.id = obj.getT(.string, "id").?,
.bot = obj.getT(.boolean, "bot") orelse false,
.username = obj.getT(.string, "username").?,
.accent_color = if (obj.getT(.integer, "accent_color")) |ac| @as(isize, @intCast(ac)) else null,
// note: for selfbots this can be typed with an enu.?,
.flags = if (obj.getT(.integer, "flags")) |fs| @as(isize, @intCast(fs)) else null,
// also for selfbot.?,
.email = obj.getT(.string, "email"),
.avatar = obj.getT(.string, "avatar"),
.locale = obj.getT(.string, "locale"),
.system = obj.getT(.boolean, "system"),
.banner = obj.getT(.string, "banner"),
.verified = obj.getT(.boolean, "verified"),
.global_name = obj.getT(.string, "global_name"),
.mfa_enabled = obj.getT(.boolean, "mfa_enabled"),
.public_flags = if (obj.getT(.integer, "public_flags")) |pfs| @as(isize, @intCast(pfs)) else null,
.premium_type = if (obj.getT(.integer, "premium_type")) |pfs| @as(Discord.PremiumTypes, @enumFromInt(pfs)) else null,
.discriminator = obj.getT(.string, "discriminator").?,
.avatar_decoration_data = if (avatar_decoration_data_obj) |add| Discord.AvatarDecorationData{
.asset = add.getT(.string, "asset").?,
.sku_id = add.getT(.string, "sku_id").?,
} else null,
};
return user;
}
pub fn parseMember(obj: *zmpl.Data.Object) Discord.Member {
const avatar_decoration_data_member_obj = obj.getT(.object, "avatar_decoration_data");
const member = Discord.Member{
.deaf = obj.getT(.boolean, "deaf"),
.mute = obj.getT(.boolean, "mute"),
.pending = obj.getT(.boolean, "pending"),
.user = null,
.nick = obj.getT(.string, "nick"),
.avatar = obj.getT(.string, "avatar"),
.roles = &[0][]const u8{},
.joined_at = obj.getT(.string, "joined_at").?,
.premium_since = obj.getT(.string, "premium_since"),
.permissions = obj.getT(.string, "permissions"),
.communication_disabled_until = obj.getT(.string, "communication_disabled_until"),
.flags = @as(isize, @intCast(obj.getT(.integer, "flags").?)),
.avatar_decoration_data = if (avatar_decoration_data_member_obj) |addm| Discord.AvatarDecorationData{
.asset = addm.getT(.string, "asset").?,
.sku_id = addm.getT(.string, "sku_id").?,
} else null,
};
return member;
}
pub fn parseMessage(obj: *zmpl.Data.Object) Discord.Message {
var buf: [1000]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buf);
// parse mentions
const mentions_obj = obj.getT(.array, "mentions").?;
var mentions = std.ArrayList(Discord.User).init(fba.allocator());
defer mentions.deinit();
while (mentions_obj.iterator().next()) |m| {
mentions.append(parseUser(&m.object)) catch unreachable;
}
// parse member
const member = parseMember(obj.getT(.object, "member").?);
// parse message
const author = parseUser(obj.getT(.object, "author").?);
//_ = if (obj.getT(.object, "referenced_message")) |m| parseMessage(m) else null;
// parse message
const message = Discord.Message{
// the id
.id = obj.getT(.string, "id").?,
.tts = obj.getT(.boolean, "tts").?,
.mention_everyone = obj.getT(.boolean, "mention_everyone").?,
.pinned = obj.getT(.boolean, "pinned").?,
.type = @as(Discord.MessageTypes, @enumFromInt(obj.getT(.integer, "type").?)),
.channel_id = obj.getT(.string, "channel_id").?,
.author = author,
.member = member,
.content = obj.getT(.string, "content"),
.timestamp = obj.getT(.string, "timestamp").?,
.guild_id = obj.getT(.string, "guild_id"),
.attachments = &[0]Discord.Attachment{},
.edited_timestamp = null,
.mentions = mentions.items,
.mention_roles = &[0]?[]const u8{},
.mention_channels = &[0]?Discord.ChannelMention{},
.embeds = &[0]Discord.Embed{},
.reactions = &[0]?Discord.Reaction{},
.nonce = .{ .string = obj.getT(.string, "nonce").? },
.webhook_id = obj.getT(.string, "webhook_id"),
.activity = null,
.application = null,
.application_id = obj.getT(.string, "application_id"),
.message_reference = null,
.flags = if (obj.getT(.integer, "flags")) |fs| @as(Discord.MessageFlags, @bitCast(@as(u15, @intCast(fs)))) else null,
.stickers = &[0]?Discord.Sticker{},
.message_snapshots = &[0]?Discord.MessageSnapshot{},
.interaction_metadata = null,
.interaction = null,
.thread = null,
.components = null,
.sticker_items = &[0]?Discord.StickerItem{},
.position = if (obj.getT(.integer, "position")) |p| @as(isize, @intCast(p)) else null,
.poll = null,
.call = null,
.referenced_message = null,
};
return message;
}