using Catalogger.Backend.Database.Redis; using Remora.Discord.API; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Objects; using Remora.Rest.Core; namespace Catalogger.Backend.Cache.RedisCache; public class RedisInviteCache(RedisService redisService) : IInviteCache { public async Task> TryGetAsync(Snowflake guildId) { var redisInvites = await redisService.GetAsync>(InvitesKey(guildId)) ?? []; return redisInvites.Select(r => r.ToRemoraInvite()); } public async Task SetAsync(Snowflake guildId, IEnumerable invites) => await redisService.SetAsync(InvitesKey(guildId), invites.Select(RedisInvite.FromIInvite)); private static string InvitesKey(Snowflake guildId) => $"guild-invites:{guildId}"; } internal record RedisInvite( string Code, RedisPartialGuild? Guild, RedisPartialChannel? Channel, RedisUser? Inviter, DateTimeOffset? ExpiresAt) { public static RedisInvite FromIInvite(IInvite invite) => new(invite.Code, invite.Guild.Map(RedisPartialGuild.FromIPartialGuild).OrDefault(), invite.Channel != null ? RedisPartialChannel.FromIPartialChannel(invite.Channel) : null, invite.Inviter.Map(RedisUser.FromIUser).OrDefault(), invite.ExpiresAt.OrDefault()); public Invite ToRemoraInvite() => new(Code, Guild?.ToRemoraPartialGuild() ?? new Optional(), Channel?.ToRemoraPartialChannel(), Inviter?.ToRemoraUser() ?? new Optional(), ExpiresAt: ExpiresAt); } internal record RedisPartialGuild(ulong Id, string? Name) { public static RedisPartialGuild FromIPartialGuild(IPartialGuild guild) => new(guild.ID.Value.Value, guild.Name.OrDefault(null)); public PartialGuild ToRemoraPartialGuild() => new(DiscordSnowflake.New(Id), Name ?? new Optional()); } internal record RedisPartialChannel(ulong Id, string? Name) { public static RedisPartialChannel FromIPartialChannel(IPartialChannel channel) => new(channel.ID.Value.Value, channel.Name.OrDefault(null)); public PartialChannel ToRemoraPartialChannel() => new(DiscordSnowflake.New(Id), Name: Name); }