-- | Things that can be upgraded from snowflakes to their full data
module Calamity.Types.Upgradeable
    ( Upgradeable(..) ) where

import           Calamity.Cache.Eff
import           Calamity.Client.Types
import           Calamity.HTTP                  as H
import           Calamity.Internal.Utils
import qualified Calamity.Internal.SnowflakeMap as SM
import           Calamity.Types.Model.Channel
import           Calamity.Types.Model.Guild
import           Calamity.Types.Model.User
import           Calamity.Types.Snowflake
import           Control.Applicative
import           Optics
import qualified Polysemy                       as P
import qualified Polysemy.Fail                  as P
import qualified Polysemy.NonDet                as P

-- | A typeclass that represents snowflakes that can be upgraded to their
-- complete data, either through the cache or HTTP.
class Upgradeable a ids | a -> ids, ids -> a where
  -- | Upgrade a snowflake to its complete data.
  --
  -- If it existed in the cache then it is returned from there, otherwise we
  -- fetch from HTTP and update the cache on success.
  upgrade :: BotC r => ids -> P.Sem r (Maybe a)

maybeToAlt :: Alternative f => Maybe a -> f a
maybeToAlt :: forall (f :: * -> *) a. Alternative f => Maybe a -> f a
maybeToAlt (Just a
x) = a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
maybeToAlt Maybe a
Nothing = f a
forall (f :: * -> *) a. Alternative f => f a
empty

instance Upgradeable User (Snowflake User) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake User -> Sem r (Maybe User)
upgrade Snowflake User
uid = Sem (NonDet : r) User -> Sem r (Maybe User)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe ((Snowflake User -> Sem (NonDet : r) (Maybe User)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake User -> Sem r (Maybe User)
getUser Snowflake User
uid Sem (NonDet : r) (Maybe User)
-> (Maybe User -> Sem (NonDet : r) User) -> Sem (NonDet : r) User
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe User -> Sem (NonDet : r) User
forall (f :: * -> *) a. Alternative f => Maybe a -> f a
maybeToAlt) Sem (NonDet : r) User
-> Sem (NonDet : r) User -> Sem (NonDet : r) User
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) User
gethttp)
    where
      gethttp :: Sem (NonDet : r) User
gethttp = Sem (Fail : NonDet : r) User -> Sem (NonDet : r) User
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) User -> Sem (NonDet : r) User)
-> Sem (Fail : NonDet : r) User -> Sem (NonDet : r) User
forall a b. (a -> b) -> a -> b
$ do
        Right User
u <- UserRequest User
-> Sem
     (Fail : NonDet : r) (Either RestError (Result (UserRequest User)))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (UserRequest User
 -> Sem
      (Fail : NonDet : r) (Either RestError (Result (UserRequest User))))
-> UserRequest User
-> Sem
     (Fail : NonDet : r) (Either RestError (Result (UserRequest User)))
forall a b. (a -> b) -> a -> b
$ Snowflake User -> UserRequest User
forall u. HasID User u => u -> UserRequest User
H.GetUser Snowflake User
uid
        User -> Sem (Fail : NonDet : r) ()
forall (r :: EffectRow). Member CacheEff r => User -> Sem r ()
setUser User
u
        User -> Sem (Fail : NonDet : r) User
forall (f :: * -> *) a. Applicative f => a -> f a
pure User
u

instance Upgradeable Member (Snowflake Guild, Snowflake Member) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
(Snowflake Guild, Snowflake Member) -> Sem r (Maybe Member)
upgrade (Snowflake Guild
gid, Snowflake Member
mid) = Sem (NonDet : r) Member -> Sem r (Maybe Member)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe (Sem (NonDet : r) Member
getcache Sem (NonDet : r) Member
-> Sem (NonDet : r) Member -> Sem (NonDet : r) Member
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) Member
gethttp)
    where
      getcache :: Sem (NonDet : r) Member
getcache = Sem (Fail : NonDet : r) Member -> Sem (NonDet : r) Member
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Member -> Sem (NonDet : r) Member)
-> Sem (Fail : NonDet : r) Member -> Sem (NonDet : r) Member
forall a b. (a -> b) -> a -> b
$ do
        Just Guild
g <- Snowflake Guild -> Sem (Fail : NonDet : r) (Maybe Guild)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> Sem r (Maybe Guild)
getGuild Snowflake Guild
gid
        Just Member
m <- Maybe Member -> Sem (Fail : NonDet : r) (Maybe Member)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Guild
g Guild -> Optic' A_Lens NoIx Guild (Maybe Member) -> Maybe Member
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Member) (SnowflakeMap Member)
#members Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Member) (SnowflakeMap Member)
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap Member)
     (SnowflakeMap Member)
     (Maybe Member)
     (Maybe Member)
-> Optic' A_Lens NoIx Guild (Maybe Member)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Index (SnowflakeMap Member)
-> Lens'
     (SnowflakeMap Member) (Maybe (IxValue (SnowflakeMap Member)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (SnowflakeMap Member)
Snowflake Member
mid)
        Member -> Sem (Fail : NonDet : r) Member
forall (f :: * -> *) a. Applicative f => a -> f a
pure Member
m
      gethttp :: Sem (NonDet : r) Member
gethttp = Sem (Fail : NonDet : r) Member -> Sem (NonDet : r) Member
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Member -> Sem (NonDet : r) Member)
-> Sem (Fail : NonDet : r) Member -> Sem (NonDet : r) Member
forall a b. (a -> b) -> a -> b
$ do
        Right Member
m <- GuildRequest Member
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (GuildRequest Member)))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (GuildRequest Member
 -> Sem
      (Fail : NonDet : r)
      (Either RestError (Result (GuildRequest Member))))
-> GuildRequest Member
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (GuildRequest Member)))
forall a b. (a -> b) -> a -> b
$ Snowflake Guild -> Snowflake User -> GuildRequest Member
forall g u.
(HasID Guild g, HasID User u) =>
g -> u -> GuildRequest Member
H.GetGuildMember Snowflake Guild
gid (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @User Snowflake Member
mid)
        -- getcache could have failed becuase the member wasn't cached
        Snowflake Guild -> (Guild -> Guild) -> Sem (Fail : NonDet : r) ()
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> (Guild -> Guild) -> Sem r ()
updateGuild Snowflake Guild
gid (Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Member) (SnowflakeMap Member)
#members Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Member) (SnowflakeMap Member)
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap Member)
     (SnowflakeMap Member)
     (Maybe (IxValue (SnowflakeMap Member)))
     (Maybe Member)
-> Optic
     A_Lens
     NoIx
     Guild
     Guild
     (Maybe (IxValue (SnowflakeMap Member)))
     (Maybe Member)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Index (SnowflakeMap Member)
-> Lens'
     (SnowflakeMap Member) (Maybe (IxValue (SnowflakeMap Member)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (SnowflakeMap Member)
Snowflake Member
mid Optic
  A_Lens
  NoIx
  Guild
  Guild
  (Maybe (IxValue (SnowflakeMap Member)))
  (Maybe Member)
-> Member -> Guild -> Guild
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a (Maybe b) -> b -> s -> t
?~ Member
m)
        Member -> Sem (Fail : NonDet : r) Member
forall (f :: * -> *) a. Applicative f => a -> f a
pure Member
m

instance Upgradeable Guild (Snowflake Guild) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake Guild -> Sem r (Maybe Guild)
upgrade Snowflake Guild
gid = Sem (NonDet : r) Guild -> Sem r (Maybe Guild)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe ((Snowflake Guild -> Sem (NonDet : r) (Maybe Guild)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> Sem r (Maybe Guild)
getGuild Snowflake Guild
gid Sem (NonDet : r) (Maybe Guild)
-> (Maybe Guild -> Sem (NonDet : r) Guild)
-> Sem (NonDet : r) Guild
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Guild -> Sem (NonDet : r) Guild
forall (f :: * -> *) a. Alternative f => Maybe a -> f a
maybeToAlt) Sem (NonDet : r) Guild
-> Sem (NonDet : r) Guild -> Sem (NonDet : r) Guild
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) Guild
gethttp)
    where
      gethttp :: Sem (NonDet : r) Guild
gethttp = Sem (Fail : NonDet : r) Guild -> Sem (NonDet : r) Guild
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Guild -> Sem (NonDet : r) Guild)
-> Sem (Fail : NonDet : r) Guild -> Sem (NonDet : r) Guild
forall a b. (a -> b) -> a -> b
$ do
        Right Guild
g <- GuildRequest Guild
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (GuildRequest Guild)))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (GuildRequest Guild
 -> Sem
      (Fail : NonDet : r)
      (Either RestError (Result (GuildRequest Guild))))
-> GuildRequest Guild
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (GuildRequest Guild)))
forall a b. (a -> b) -> a -> b
$ Snowflake Guild -> GuildRequest Guild
forall g. HasID Guild g => g -> GuildRequest Guild
H.GetGuild Snowflake Guild
gid
        Guild -> Sem (Fail : NonDet : r) Guild
forall (f :: * -> *) a. Applicative f => a -> f a
pure Guild
g

insertChannel :: BotC r => Channel -> P.Sem r ()
insertChannel :: forall (r :: EffectRow). BotC r => Channel -> Sem r ()
insertChannel (DMChannel' DMChannel
dm) = DMChannel -> Sem r ()
forall (r :: EffectRow). Member CacheEff r => DMChannel -> Sem r ()
setDM DMChannel
dm
insertChannel (GuildChannel' GuildChannel
ch) =
  Snowflake Guild -> (Guild -> Guild) -> Sem r ()
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> (Guild -> Guild) -> Sem r ()
updateGuild (GuildChannel -> Snowflake Guild
forall b a. HasID b a => a -> Snowflake b
getID GuildChannel
ch) (Optic
  A_Lens
  NoIx
  Guild
  Guild
  (SnowflakeMap GuildChannel)
  (SnowflakeMap GuildChannel)
#channels Optic
  A_Lens
  NoIx
  Guild
  Guild
  (SnowflakeMap GuildChannel)
  (SnowflakeMap GuildChannel)
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap GuildChannel)
     (SnowflakeMap GuildChannel)
     (Maybe (IxValue (SnowflakeMap GuildChannel)))
     (Maybe GuildChannel)
-> Optic
     A_Lens
     NoIx
     Guild
     Guild
     (Maybe (IxValue (SnowflakeMap GuildChannel)))
     (Maybe GuildChannel)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Index (SnowflakeMap GuildChannel)
-> Lens'
     (SnowflakeMap GuildChannel)
     (Maybe (IxValue (SnowflakeMap GuildChannel)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at (forall b a. HasID b a => a -> Snowflake b
getID @GuildChannel GuildChannel
ch) Optic
  A_Lens
  NoIx
  Guild
  Guild
  (Maybe (IxValue (SnowflakeMap GuildChannel)))
  (Maybe GuildChannel)
-> GuildChannel -> Guild -> Guild
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a (Maybe b) -> b -> s -> t
?~ GuildChannel
ch)
insertChannel Channel
_ = () -> Sem r ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

instance Upgradeable Channel (Snowflake Channel) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake Channel -> Sem r (Maybe Channel)
upgrade Snowflake Channel
cid = Sem (NonDet : r) Channel -> Sem r (Maybe Channel)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe (Sem (NonDet : r) Channel
getcacheDM Sem (NonDet : r) Channel
-> Sem (NonDet : r) Channel -> Sem (NonDet : r) Channel
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) Channel
getcacheGuild Sem (NonDet : r) Channel
-> Sem (NonDet : r) Channel -> Sem (NonDet : r) Channel
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) Channel
gethttp)
    where
      getcacheDM :: Sem (NonDet : r) Channel
getcacheDM = DMChannel -> Channel
DMChannel' (DMChannel -> Channel)
-> Sem (NonDet : r) (Maybe DMChannel)
-> Sem (NonDet : r) (Maybe Channel)
forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<<$>> Snowflake DMChannel -> Sem (NonDet : r) (Maybe DMChannel)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake DMChannel -> Sem r (Maybe DMChannel)
getDM (Snowflake Channel -> Snowflake DMChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake Snowflake Channel
cid) Sem (NonDet : r) (Maybe Channel)
-> (Maybe Channel -> Sem (NonDet : r) Channel)
-> Sem (NonDet : r) Channel
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Channel -> Sem (NonDet : r) Channel
forall (f :: * -> *) a. Alternative f => Maybe a -> f a
maybeToAlt
      getcacheGuild :: Sem (NonDet : r) Channel
getcacheGuild = GuildChannel -> Channel
GuildChannel' (GuildChannel -> Channel)
-> Sem (NonDet : r) (Maybe GuildChannel)
-> Sem (NonDet : r) (Maybe Channel)
forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<<$>> Snowflake GuildChannel -> Sem (NonDet : r) (Maybe GuildChannel)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake GuildChannel -> Sem r (Maybe GuildChannel)
getGuildChannel (Snowflake Channel -> Snowflake GuildChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake Snowflake Channel
cid) Sem (NonDet : r) (Maybe Channel)
-> (Maybe Channel -> Sem (NonDet : r) Channel)
-> Sem (NonDet : r) Channel
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Channel -> Sem (NonDet : r) Channel
forall (f :: * -> *) a. Alternative f => Maybe a -> f a
maybeToAlt
      gethttp :: Sem (NonDet : r) Channel
gethttp = Sem (Fail : NonDet : r) Channel -> Sem (NonDet : r) Channel
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Channel -> Sem (NonDet : r) Channel)
-> Sem (Fail : NonDet : r) Channel -> Sem (NonDet : r) Channel
forall a b. (a -> b) -> a -> b
$ do
        Right Channel
c <- ChannelRequest Channel
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (ChannelRequest Channel)))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (ChannelRequest Channel
 -> Sem
      (Fail : NonDet : r)
      (Either RestError (Result (ChannelRequest Channel))))
-> ChannelRequest Channel
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (ChannelRequest Channel)))
forall a b. (a -> b) -> a -> b
$ Snowflake Channel -> ChannelRequest Channel
forall c. HasID Channel c => c -> ChannelRequest Channel
H.GetChannel Snowflake Channel
cid
        Channel -> Sem (Fail : NonDet : r) ()
forall (r :: EffectRow). BotC r => Channel -> Sem r ()
insertChannel Channel
c
        Channel -> Sem (Fail : NonDet : r) Channel
forall (f :: * -> *) a. Applicative f => a -> f a
pure Channel
c

instance Upgradeable GuildChannel (Snowflake GuildChannel) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake GuildChannel -> Sem r (Maybe GuildChannel)
upgrade Snowflake GuildChannel
cid = Sem (NonDet : r) GuildChannel -> Sem r (Maybe GuildChannel)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe (Sem (NonDet : r) GuildChannel
getcache Sem (NonDet : r) GuildChannel
-> Sem (NonDet : r) GuildChannel -> Sem (NonDet : r) GuildChannel
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) GuildChannel
gethttp)
    where
      getcache :: Sem (NonDet : r) GuildChannel
getcache = Snowflake GuildChannel -> Sem (NonDet : r) (Maybe GuildChannel)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake GuildChannel -> Sem r (Maybe GuildChannel)
getGuildChannel (Snowflake GuildChannel -> Snowflake GuildChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake Snowflake GuildChannel
cid) Sem (NonDet : r) (Maybe GuildChannel)
-> (Maybe GuildChannel -> Sem (NonDet : r) GuildChannel)
-> Sem (NonDet : r) GuildChannel
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe GuildChannel -> Sem (NonDet : r) GuildChannel
forall (f :: * -> *) a. Alternative f => Maybe a -> f a
maybeToAlt
      gethttp :: Sem (NonDet : r) GuildChannel
gethttp = Sem (Fail : NonDet : r) GuildChannel
-> Sem (NonDet : r) GuildChannel
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) GuildChannel
 -> Sem (NonDet : r) GuildChannel)
-> Sem (Fail : NonDet : r) GuildChannel
-> Sem (NonDet : r) GuildChannel
forall a b. (a -> b) -> a -> b
$ do
        Right Channel
c <- ChannelRequest Channel
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (ChannelRequest Channel)))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (ChannelRequest Channel
 -> Sem
      (Fail : NonDet : r)
      (Either RestError (Result (ChannelRequest Channel))))
-> ChannelRequest Channel
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (ChannelRequest Channel)))
forall a b. (a -> b) -> a -> b
$ Snowflake Channel -> ChannelRequest Channel
forall c. HasID Channel c => c -> ChannelRequest Channel
H.GetChannel (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @Channel Snowflake GuildChannel
cid)
        Channel -> Sem (Fail : NonDet : r) ()
forall (r :: EffectRow). BotC r => Channel -> Sem r ()
insertChannel Channel
c
        GuildChannel' GuildChannel
c' <- Channel -> Sem (Fail : NonDet : r) Channel
forall (f :: * -> *) a. Applicative f => a -> f a
pure Channel
c
        GuildChannel -> Sem (Fail : NonDet : r) GuildChannel
forall (f :: * -> *) a. Applicative f => a -> f a
pure GuildChannel
c'

instance Upgradeable VoiceChannel (Snowflake VoiceChannel) where
    upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake VoiceChannel -> Sem r (Maybe VoiceChannel)
upgrade Snowflake VoiceChannel
s = Snowflake Channel -> Sem r (Maybe Channel)
forall a ids (r :: EffectRow).
(Upgradeable a ids, BotC r) =>
ids -> Sem r (Maybe a)
upgrade (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @Channel Snowflake VoiceChannel
s) Sem r (Maybe Channel)
-> (Maybe Channel -> Maybe VoiceChannel)
-> Sem r (Maybe VoiceChannel)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            Just (GuildChannel' (GuildVoiceChannel VoiceChannel
vc)) -> VoiceChannel -> Maybe VoiceChannel
forall a. a -> Maybe a
Just VoiceChannel
vc
            Maybe Channel
_ -> Maybe VoiceChannel
forall a. Maybe a
Nothing

instance Upgradeable DMChannel (Snowflake DMChannel) where
    upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake DMChannel -> Sem r (Maybe DMChannel)
upgrade Snowflake DMChannel
s = Snowflake Channel -> Sem r (Maybe Channel)
forall a ids (r :: EffectRow).
(Upgradeable a ids, BotC r) =>
ids -> Sem r (Maybe a)
upgrade (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @Channel Snowflake DMChannel
s) Sem r (Maybe Channel)
-> (Maybe Channel -> Maybe DMChannel) -> Sem r (Maybe DMChannel)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            Just (DMChannel' DMChannel
dc) -> DMChannel -> Maybe DMChannel
forall a. a -> Maybe a
Just DMChannel
dc
            Maybe Channel
_ -> Maybe DMChannel
forall a. Maybe a
Nothing

instance Upgradeable GroupChannel (Snowflake GroupChannel) where
    upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake GroupChannel -> Sem r (Maybe GroupChannel)
upgrade Snowflake GroupChannel
s = Snowflake Channel -> Sem r (Maybe Channel)
forall a ids (r :: EffectRow).
(Upgradeable a ids, BotC r) =>
ids -> Sem r (Maybe a)
upgrade (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @Channel Snowflake GroupChannel
s) Sem r (Maybe Channel)
-> (Maybe Channel -> Maybe GroupChannel)
-> Sem r (Maybe GroupChannel)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            Just (GroupChannel' GroupChannel
gc) -> GroupChannel -> Maybe GroupChannel
forall a. a -> Maybe a
Just GroupChannel
gc
            Maybe Channel
_ -> Maybe GroupChannel
forall a. Maybe a
Nothing

instance Upgradeable TextChannel (Snowflake TextChannel) where
    upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake TextChannel -> Sem r (Maybe TextChannel)
upgrade Snowflake TextChannel
s = Snowflake Channel -> Sem r (Maybe Channel)
forall a ids (r :: EffectRow).
(Upgradeable a ids, BotC r) =>
ids -> Sem r (Maybe a)
upgrade (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @Channel Snowflake TextChannel
s) Sem r (Maybe Channel)
-> (Maybe Channel -> Maybe TextChannel)
-> Sem r (Maybe TextChannel)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            Just (GuildChannel' (GuildTextChannel TextChannel
tc)) -> TextChannel -> Maybe TextChannel
forall a. a -> Maybe a
Just TextChannel
tc
            Maybe Channel
_ -> Maybe TextChannel
forall a. Maybe a
Nothing

instance Upgradeable Category (Snowflake Category) where
    upgrade :: forall (r :: EffectRow).
BotC r =>
Snowflake Category -> Sem r (Maybe Category)
upgrade Snowflake Category
s = Snowflake Channel -> Sem r (Maybe Channel)
forall a ids (r :: EffectRow).
(Upgradeable a ids, BotC r) =>
ids -> Sem r (Maybe a)
upgrade (forall a b. Snowflake a -> Snowflake b
coerceSnowflake @_ @Channel Snowflake Category
s) Sem r (Maybe Channel)
-> (Maybe Channel -> Maybe Category) -> Sem r (Maybe Category)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            Just (GuildChannel' (GuildCategory Category
c)) -> Category -> Maybe Category
forall a. a -> Maybe a
Just Category
c
            Maybe Channel
_ -> Maybe Category
forall a. Maybe a
Nothing


instance Upgradeable Emoji (Snowflake Guild, Snowflake Emoji) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
(Snowflake Guild, Snowflake Emoji) -> Sem r (Maybe Emoji)
upgrade (Snowflake Guild
gid, Snowflake Emoji
eid) = Sem (NonDet : r) Emoji -> Sem r (Maybe Emoji)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe (Sem (NonDet : r) Emoji
getcache Sem (NonDet : r) Emoji
-> Sem (NonDet : r) Emoji -> Sem (NonDet : r) Emoji
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) Emoji
gethttp)
    where
      getcache :: Sem (NonDet : r) Emoji
getcache = Sem (Fail : NonDet : r) Emoji -> Sem (NonDet : r) Emoji
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Emoji -> Sem (NonDet : r) Emoji)
-> Sem (Fail : NonDet : r) Emoji -> Sem (NonDet : r) Emoji
forall a b. (a -> b) -> a -> b
$ do
        Just Guild
g <- Snowflake Guild -> Sem (Fail : NonDet : r) (Maybe Guild)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> Sem r (Maybe Guild)
getGuild Snowflake Guild
gid
        Just Emoji
m <- Maybe Emoji -> Sem (Fail : NonDet : r) (Maybe Emoji)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Guild
g Guild -> Optic' A_Lens NoIx Guild (Maybe Emoji) -> Maybe Emoji
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Emoji) (SnowflakeMap Emoji)
#emojis Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Emoji) (SnowflakeMap Emoji)
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap Emoji)
     (SnowflakeMap Emoji)
     (Maybe Emoji)
     (Maybe Emoji)
-> Optic' A_Lens NoIx Guild (Maybe Emoji)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Index (SnowflakeMap Emoji)
-> Lens'
     (SnowflakeMap Emoji) (Maybe (IxValue (SnowflakeMap Emoji)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (SnowflakeMap Emoji)
Snowflake Emoji
eid)
        Emoji -> Sem (Fail : NonDet : r) Emoji
forall (f :: * -> *) a. Applicative f => a -> f a
pure Emoji
m
      gethttp :: Sem (NonDet : r) Emoji
gethttp = Sem (Fail : NonDet : r) Emoji -> Sem (NonDet : r) Emoji
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Emoji -> Sem (NonDet : r) Emoji)
-> Sem (Fail : NonDet : r) Emoji -> Sem (NonDet : r) Emoji
forall a b. (a -> b) -> a -> b
$ do
        Right Emoji
e <- EmojiRequest Emoji
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (EmojiRequest Emoji)))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (EmojiRequest Emoji
 -> Sem
      (Fail : NonDet : r)
      (Either RestError (Result (EmojiRequest Emoji))))
-> EmojiRequest Emoji
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (EmojiRequest Emoji)))
forall a b. (a -> b) -> a -> b
$ Snowflake Guild -> Snowflake Emoji -> EmojiRequest Emoji
forall g e.
(HasID Guild g, HasID Emoji e) =>
g -> e -> EmojiRequest Emoji
H.GetGuildEmoji Snowflake Guild
gid Snowflake Emoji
eid
        Snowflake Guild -> (Guild -> Guild) -> Sem (Fail : NonDet : r) ()
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> (Guild -> Guild) -> Sem r ()
updateGuild Snowflake Guild
gid (Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Emoji) (SnowflakeMap Emoji)
#emojis Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Emoji) (SnowflakeMap Emoji)
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap Emoji)
     (SnowflakeMap Emoji)
     (Maybe (IxValue (SnowflakeMap Emoji)))
     (Maybe Emoji)
-> Optic
     A_Lens
     NoIx
     Guild
     Guild
     (Maybe (IxValue (SnowflakeMap Emoji)))
     (Maybe Emoji)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Index (SnowflakeMap Emoji)
-> Lens'
     (SnowflakeMap Emoji) (Maybe (IxValue (SnowflakeMap Emoji)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (SnowflakeMap Emoji)
Snowflake Emoji
eid Optic
  A_Lens
  NoIx
  Guild
  Guild
  (Maybe (IxValue (SnowflakeMap Emoji)))
  (Maybe Emoji)
-> Emoji -> Guild -> Guild
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a (Maybe b) -> b -> s -> t
?~ Emoji
e)
        Emoji -> Sem (Fail : NonDet : r) Emoji
forall (f :: * -> *) a. Applicative f => a -> f a
pure Emoji
e

instance Upgradeable Role (Snowflake Guild, Snowflake Role) where
  upgrade :: forall (r :: EffectRow).
BotC r =>
(Snowflake Guild, Snowflake Role) -> Sem r (Maybe Role)
upgrade (Snowflake Guild
gid, Snowflake Role
rid) = Sem (NonDet : r) Role -> Sem r (Maybe Role)
forall (r :: EffectRow) a. Sem (NonDet : r) a -> Sem r (Maybe a)
P.runNonDetMaybe (Sem (NonDet : r) Role
getcache Sem (NonDet : r) Role
-> Sem (NonDet : r) Role -> Sem (NonDet : r) Role
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Sem (NonDet : r) Role
gethttp)
    where
      getcache :: Sem (NonDet : r) Role
getcache = Sem (Fail : NonDet : r) Role -> Sem (NonDet : r) Role
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Role -> Sem (NonDet : r) Role)
-> Sem (Fail : NonDet : r) Role -> Sem (NonDet : r) Role
forall a b. (a -> b) -> a -> b
$ do
        Just Guild
g <- Snowflake Guild -> Sem (Fail : NonDet : r) (Maybe Guild)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> Sem r (Maybe Guild)
getGuild Snowflake Guild
gid
        Just Role
r <- Maybe Role -> Sem (Fail : NonDet : r) (Maybe Role)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Guild
g Guild -> Optic' A_Lens NoIx Guild (Maybe Role) -> Maybe Role
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Role) (SnowflakeMap Role)
#roles Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Role) (SnowflakeMap Role)
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap Role)
     (SnowflakeMap Role)
     (Maybe Role)
     (Maybe Role)
-> Optic' A_Lens NoIx Guild (Maybe Role)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Index (SnowflakeMap Role)
-> Lens' (SnowflakeMap Role) (Maybe (IxValue (SnowflakeMap Role)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (SnowflakeMap Role)
Snowflake Role
rid)
        Role -> Sem (Fail : NonDet : r) Role
forall (f :: * -> *) a. Applicative f => a -> f a
pure Role
r
      gethttp :: Sem (NonDet : r) Role
gethttp = Sem (Fail : NonDet : r) Role -> Sem (NonDet : r) Role
forall (r :: EffectRow) a.
Member NonDet r =>
Sem (Fail : r) a -> Sem r a
P.failToNonDet (Sem (Fail : NonDet : r) Role -> Sem (NonDet : r) Role)
-> Sem (Fail : NonDet : r) Role -> Sem (NonDet : r) Role
forall a b. (a -> b) -> a -> b
$ do
        Right [Role]
rs <- GuildRequest [Role]
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (GuildRequest [Role])))
forall (r :: EffectRow) a.
(Members '[RatelimitEff, TokenEff, LogEff, MetricEff, Embed IO] r,
 Request a, ReadResponse (Result a)) =>
a -> Sem r (Either RestError (Result a))
invoke (GuildRequest [Role]
 -> Sem
      (Fail : NonDet : r)
      (Either RestError (Result (GuildRequest [Role]))))
-> GuildRequest [Role]
-> Sem
     (Fail : NonDet : r)
     (Either RestError (Result (GuildRequest [Role])))
forall a b. (a -> b) -> a -> b
$ Snowflake Guild -> GuildRequest [Role]
forall g. HasID Guild g => g -> GuildRequest [Role]
H.GetGuildRoles Snowflake Guild
gid
        let sm :: SnowflakeMap Role
sm = [Role] -> SnowflakeMap Role
forall a. HasID' a => [a] -> SnowflakeMap a
SM.fromList [Role]
rs
        Snowflake Guild -> (Guild -> Guild) -> Sem (Fail : NonDet : r) ()
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> (Guild -> Guild) -> Sem r ()
updateGuild Snowflake Guild
gid (Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Role) (SnowflakeMap Role)
#roles Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Role) (SnowflakeMap Role)
-> (SnowflakeMap Role -> SnowflakeMap Role) -> Guild -> Guild
forall k (is :: IxList) s t a b.
Is k A_Setter =>
Optic k is s t a b -> (a -> b) -> s -> t
%~ (SnowflakeMap Role -> SnowflakeMap Role -> SnowflakeMap Role
forall a. Semigroup a => a -> a -> a
<> SnowflakeMap Role
sm))
        Just Role
r <- Maybe Role -> Sem (Fail : NonDet : r) (Maybe Role)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SnowflakeMap Role
sm SnowflakeMap Role
-> Optic
     A_Lens
     NoIx
     (SnowflakeMap Role)
     (SnowflakeMap Role)
     (Maybe Role)
     (Maybe Role)
-> Maybe Role
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Index (SnowflakeMap Role)
-> Lens' (SnowflakeMap Role) (Maybe (IxValue (SnowflakeMap Role)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (SnowflakeMap Role)
Snowflake Role
rid)
        Role -> Sem (Fail : NonDet : r) Role
forall (f :: * -> *) a. Applicative f => a -> f a
pure Role
r