-- | Updateable objects module Calamity.Internal.Updateable (Updateable (..)) where import Calamity.Internal.Utils import Calamity.Types.Model.Channel import Calamity.Types.Model.Channel.UpdatedMessage import Calamity.Types.Model.Guild.Guild import Calamity.Types.Model.User import Data.Maybe import GHC.TypeLits import Optics class Updateable a where type Updated a type Updated a = a update :: Updated a -> a -> a -- | sets original field to new field setF :: forall (f :: Symbol) o n b k. ( k ~ A_Lens , LabelOptic' f k o b , LabelOptic' f k n b ) => n -> o -> o setF n = labelOptic @f .~ n ^. labelOptic @f -- | sets original field to unwrapped new field if new field is not Nothing mergeF :: forall (f :: Symbol) o n b k. ( k ~ A_Lens , LabelOptic' f k o b , LabelOptic' f k n (Maybe b) ) => n -> o -> o mergeF n = labelOptic @f %~ \oldv -> fromMaybe oldv (n ^. labelOptic @f) -- | sets original field to new field if new field is not nothing mergeF' :: forall (f :: Symbol) old new v k. ( k ~ A_Lens , LabelOptic' f k old (Maybe v) , LabelOptic' f k new (Maybe v) ) => new -> old -> old mergeF' new = labelOptic @f %~ \oldv -> lastMaybe oldv (new ^. labelOptic @f) -- | sets original field to new field if new field was present updateNullableDest :: forall (f :: Symbol) old new v k. ( k ~ A_Lens , LabelOptic' f k old (Maybe v) , LabelOptic' f k new (Maybe (MaybeNull v)) ) => new -> old -> old updateNullableDest new = case new ^. labelOptic @f of Just (NotNull x) -> labelOptic @f ?~ x Just WasNull -> labelOptic @f .~ Nothing Nothing -> Prelude.id -- NOTE: afaik only messages get partial updates instance Updateable Message where type Updated Message = UpdatedMessage update n o = o & mergeF @"content" n & updateNullableDest @"editedTimestamp" n & mergeF @"tts" n & mergeF @"mentionEveryone" n & mergeF @"mentions" n & mergeF @"mentionRoles" n & mergeF @"mentionChannels" n & mergeF @"attachments" n & mergeF @"embeds" n & mergeF @"reactions" n & mergeF @"pinned" n & mergeF @"type_" n & updateNullableDest @"activity" n & updateNullableDest @"application" n & updateNullableDest @"messageReference" n & mergeF @"flags" n & updateNullableDest @"referencedMessage" n & updateNullableDest @"interaction" n & mergeF @"components" n instance Updateable Channel where update n _ = n instance Updateable DMChannel where update n _ = n instance Updateable GuildChannel where update n _ = n instance Updateable Guild where type Updated Guild = UpdatedGuild update n o = o & setF @"name" n & setF @"icon" n & setF @"splash" n & setF @"discoverySplash" n & setF @"banner" n & setF @"owner" n & setF @"ownerID" n & mergeF @"permissions" n & setF @"afkChannelID" n & setF @"afkTimeout" n & mergeF @"embedEnabled" n & setF @"embedChannelID" n & setF @"verificationLevel" n & setF @"defaultMessageNotifications" n & setF @"explicitContentFilter" n & setF @"roles" n & setF @"features" n & setF @"mfaLevel" n & setF @"applicationID" n & mergeF @"widgetEnabled" n & setF @"widgetChannelID" n & setF @"systemChannelID" n & setF @"preferredLocale" n instance Updateable User where update n o = o & setF @"username" n & setF @"discriminator" n & mergeF' @"bot" n & setF @"avatar" n & mergeF' @"mfaEnabled" n & mergeF' @"verified" n & mergeF' @"email" n & mergeF' @"flags" n & mergeF' @"premiumType" n