{-# LANGUAGE TemplateHaskell #-}

-- | Command invokation context
module Calamity.Commands.Context (
  CalamityCommandContext (..),
  FullContext (..),
  useFullContext,
  LightContext (..),
  useLightContext,
) where

import Calamity.Cache.Eff
import Calamity.Commands.Types
import Calamity.Internal.Utils
import Calamity.Types.Model.Channel
import Calamity.Types.Model.Guild
import Calamity.Types.Model.User
import Calamity.Types.Snowflake
import Calamity.Types.Tellable
import CalamityCommands.Context qualified as CC
import Control.Applicative
import Control.Monad
import Data.Text qualified as T
import Optics
import Polysemy qualified as P
import Polysemy.Fail qualified as P
import TextShow qualified

class CommandContext c => CalamityCommandContext c where
  -- | The id of the channel that invoked this command
  ctxChannelID :: c -> Snowflake Channel

  -- | The id of the guild the command was invoked in, if in a guild
  ctxGuildID :: c -> Maybe (Snowflake Guild)

  -- | The id of the user that invoked this command
  ctxUserID :: c -> Snowflake User

  -- | The message that triggered this command
  ctxMessage :: c -> Message

-- | Invokation context for commands
data FullContext = FullContext
  { FullContext -> Message
message :: Message
  -- ^ The message that the command was invoked from
  , FullContext -> Maybe Guild
guild :: Maybe Guild
  -- ^ If the command was sent in a guild, this will be present
  , FullContext -> Maybe Member
member :: Maybe Member
  -- ^ The member that invoked the command, if in a guild
  --
  -- Note: If discord sent a member with the message, this is used; otherwise
  -- we try to fetch the member from the cache.
  , FullContext -> Channel
channel :: Channel
  -- ^ The channel the command was invoked from
  , FullContext -> User
user :: User
  -- ^ The user that invoked the command
  , FullContext -> Command FullContext
command :: Command FullContext
  -- ^ The command that was invoked
  , FullContext -> Text
prefix :: T.Text
  -- ^ The prefix that was used to invoke the command
  , FullContext -> Text
unparsedParams :: T.Text
  -- ^ The message remaining after consuming the prefix
  }
  deriving (Int -> FullContext -> ShowS
[FullContext] -> ShowS
FullContext -> String
(Int -> FullContext -> ShowS)
-> (FullContext -> String)
-> ([FullContext] -> ShowS)
-> Show FullContext
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FullContext -> ShowS
showsPrec :: Int -> FullContext -> ShowS
$cshow :: FullContext -> String
show :: FullContext -> String
$cshowList :: [FullContext] -> ShowS
showList :: [FullContext] -> ShowS
Show)
  deriving (Int -> FullContext -> Text
Int -> FullContext -> Builder
Int -> FullContext -> Text
[FullContext] -> Text
[FullContext] -> Builder
[FullContext] -> Text
FullContext -> Text
FullContext -> Builder
FullContext -> Text
(Int -> FullContext -> Builder)
-> (FullContext -> Builder)
-> ([FullContext] -> Builder)
-> (Int -> FullContext -> Text)
-> (FullContext -> Text)
-> ([FullContext] -> Text)
-> (Int -> FullContext -> Text)
-> (FullContext -> Text)
-> ([FullContext] -> Text)
-> TextShow FullContext
forall a.
(Int -> a -> Builder)
-> (a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> TextShow a
$cshowbPrec :: Int -> FullContext -> Builder
showbPrec :: Int -> FullContext -> Builder
$cshowb :: FullContext -> Builder
showb :: FullContext -> Builder
$cshowbList :: [FullContext] -> Builder
showbList :: [FullContext] -> Builder
$cshowtPrec :: Int -> FullContext -> Text
showtPrec :: Int -> FullContext -> Text
$cshowt :: FullContext -> Text
showt :: FullContext -> Text
$cshowtList :: [FullContext] -> Text
showtList :: [FullContext] -> Text
$cshowtlPrec :: Int -> FullContext -> Text
showtlPrec :: Int -> FullContext -> Text
$cshowtl :: FullContext -> Text
showtl :: FullContext -> Text
$cshowtlList :: [FullContext] -> Text
showtlList :: [FullContext] -> Text
TextShow.TextShow) via TextShow.FromStringShow FullContext
  deriving (HasID Channel) via HasIDField "channel" FullContext
  deriving (HasID Message) via HasIDField "message" FullContext
  deriving (HasID User) via HasIDField "user" FullContext

$(makeFieldLabelsNoPrefix ''FullContext)

instance CC.CommandContext IO FullContext () where
  ctxPrefix :: FullContext -> Text
ctxPrefix = (FullContext -> Optic' A_Lens NoIx FullContext Text -> Text
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext Text
#prefix)
  ctxCommand :: FullContext -> Command FullContext
ctxCommand = (FullContext
-> Optic' A_Lens NoIx FullContext (Command FullContext)
-> Command FullContext
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext (Command FullContext)
#command)
  ctxUnparsedParams :: FullContext -> Text
ctxUnparsedParams = (FullContext -> Optic' A_Lens NoIx FullContext Text -> Text
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext Text
#unparsedParams)

instance CalamityCommandContext FullContext where
  ctxChannelID :: FullContext -> Snowflake Channel
ctxChannelID = Channel -> Snowflake Channel
forall b a. HasID b a => a -> Snowflake b
getID (Channel -> Snowflake Channel)
-> (FullContext -> Channel) -> FullContext -> Snowflake Channel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FullContext -> Optic' A_Lens NoIx FullContext Channel -> Channel
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext Channel
#channel)
  ctxGuildID :: FullContext -> Maybe (Snowflake Guild)
ctxGuildID FullContext
c = Guild -> Snowflake Guild
forall b a. HasID b a => a -> Snowflake b
getID (Guild -> Snowflake Guild)
-> Maybe Guild -> Maybe (Snowflake Guild)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FullContext
c FullContext
-> Optic' A_Lens NoIx FullContext (Maybe Guild) -> Maybe Guild
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext (Maybe Guild)
#guild
  ctxUserID :: FullContext -> Snowflake User
ctxUserID = User -> Snowflake User
forall b a. HasID b a => a -> Snowflake b
getID (User -> Snowflake User)
-> (FullContext -> User) -> FullContext -> Snowflake User
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FullContext -> Optic' A_Lens NoIx FullContext User -> User
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext User
#user)
  ctxMessage :: FullContext -> Message
ctxMessage = (FullContext -> Optic' A_Lens NoIx FullContext Message -> Message
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FullContext Message
#message)

instance Tellable FullContext where
  getChannel :: forall (r :: EffectRow).
(BotC r, Member (Error RestError) r) =>
FullContext -> Sem r (Snowflake Channel)
getChannel = Snowflake Channel -> Sem r (Snowflake Channel)
forall a. a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Snowflake Channel -> Sem r (Snowflake Channel))
-> (FullContext -> Snowflake Channel)
-> FullContext
-> Sem r (Snowflake Channel)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FullContext -> Snowflake Channel
forall c. CalamityCommandContext c => c -> Snowflake Channel
ctxChannelID

useFullContext :: P.Member CacheEff r => P.Sem (CC.ConstructContext (Message, User, Maybe Member) FullContext IO () ': r) a -> P.Sem r a
useFullContext :: forall (r :: EffectRow) a.
Member CacheEff r =>
Sem
  (ConstructContext (Message, User, Maybe Member) FullContext IO ()
     : r)
  a
-> Sem r a
useFullContext =
  (forall (rInitial :: EffectRow) x.
 ConstructContext
   (Message, User, Maybe Member) FullContext IO () (Sem rInitial) x
 -> Sem r x)
-> Sem
     (ConstructContext (Message, User, Maybe Member) FullContext IO ()
        : r)
     a
-> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
P.interpret
    ( \case
        CC.ConstructContext (Text
pre, Command FullContext
cmd, Text
up) (Message
msg, User
usr, Maybe Member
mem) -> Message
-> User
-> Maybe Member
-> Text
-> Command FullContext
-> Text
-> Sem r (Maybe FullContext)
forall (r :: EffectRow).
Member CacheEff r =>
Message
-> User
-> Maybe Member
-> Text
-> Command FullContext
-> Text
-> Sem r (Maybe FullContext)
buildContext Message
msg User
usr Maybe Member
mem Text
pre Command FullContext
cmd Text
up
    )

buildContext :: P.Member CacheEff r => Message -> User -> Maybe Member -> T.Text -> Command FullContext -> T.Text -> P.Sem r (Maybe FullContext)
buildContext :: forall (r :: EffectRow).
Member CacheEff r =>
Message
-> User
-> Maybe Member
-> Text
-> Command FullContext
-> Text
-> Sem r (Maybe FullContext)
buildContext Message
msg User
usr Maybe Member
mem Text
prefix Command FullContext
command Text
unparsed = (Either String FullContext -> Maybe FullContext
forall e a. Either e a -> Maybe a
rightToMaybe (Either String FullContext -> Maybe FullContext)
-> Sem r (Either String FullContext) -> Sem r (Maybe FullContext)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Sem r (Either String FullContext) -> Sem r (Maybe FullContext))
-> (Sem (Fail : r) FullContext
    -> Sem r (Either String FullContext))
-> Sem (Fail : r) FullContext
-> Sem r (Maybe FullContext)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem (Fail : r) FullContext -> Sem r (Either String FullContext)
forall (r :: EffectRow) a.
Sem (Fail : r) a -> Sem r (Either String a)
P.runFail (Sem (Fail : r) FullContext -> Sem r (Maybe FullContext))
-> Sem (Fail : r) FullContext -> Sem r (Maybe FullContext)
forall a b. (a -> b) -> a -> b
$ do
  Maybe Guild
guild <- Maybe (Maybe Guild) -> Maybe Guild
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Maybe (Maybe Guild) -> Maybe Guild)
-> Sem (Fail : r) (Maybe (Maybe Guild))
-> Sem (Fail : r) (Maybe Guild)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Snowflake Guild -> Sem (Fail : r) (Maybe Guild)
forall (r :: EffectRow).
Member CacheEff r =>
Snowflake Guild -> Sem r (Maybe Guild)
getGuild (Snowflake Guild -> Sem (Fail : r) (Maybe Guild))
-> Maybe (Snowflake Guild) -> Sem (Fail : r) (Maybe (Maybe Guild))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Maybe a -> f (Maybe b)
`traverse` (Message
msg Message
-> Optic' A_Lens NoIx Message (Maybe (Snowflake Guild))
-> Maybe (Snowflake Guild)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx Message (Maybe (Snowflake Guild))
#guildID)
  let member :: Maybe Member
member = Maybe Member
mem Maybe Member -> Maybe Member -> Maybe Member
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Guild
guild Maybe Guild
-> Optic' An_AffineTraversal NoIx (Maybe Guild) Member
-> Maybe Member
forall k s (is :: IxList) a.
Is k An_AffineFold =>
s -> Optic' k is s a -> Maybe a
^? Prism (Maybe Guild) (Maybe Guild) Guild Guild
forall a b. Prism (Maybe a) (Maybe b) a b
_Just Prism (Maybe Guild) (Maybe Guild) Guild Guild
-> Optic
     A_Lens NoIx Guild Guild (SnowflakeMap Member) (SnowflakeMap Member)
-> Optic
     An_AffineTraversal
     NoIx
     (Maybe Guild)
     (Maybe Guild)
     (SnowflakeMap Member)
     (SnowflakeMap 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
% Optic
  A_Lens NoIx Guild Guild (SnowflakeMap Member) (SnowflakeMap Member)
#members Optic
  An_AffineTraversal
  NoIx
  (Maybe Guild)
  (Maybe Guild)
  (SnowflakeMap Member)
  (SnowflakeMap Member)
-> Optic
     (IxKind (SnowflakeMap Member))
     NoIx
     (SnowflakeMap Member)
     (SnowflakeMap Member)
     Member
     Member
-> Optic' An_AffineTraversal NoIx (Maybe Guild) 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)
-> Optic'
     (IxKind (SnowflakeMap Member))
     NoIx
     (SnowflakeMap Member)
     (IxValue (SnowflakeMap Member))
forall m. Ixed m => Index m -> Optic' (IxKind m) NoIx m (IxValue m)
ix (Snowflake User -> Snowflake Member
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake User -> Snowflake Member)
-> Snowflake User -> Snowflake Member
forall a b. (a -> b) -> a -> b
$ forall b a. HasID b a => a -> Snowflake b
getID @User Message
msg)
  let gchan :: Maybe GuildChannel
gchan = Maybe Guild
guild Maybe Guild
-> Optic' An_AffineTraversal NoIx (Maybe Guild) GuildChannel
-> Maybe GuildChannel
forall k s (is :: IxList) a.
Is k An_AffineFold =>
s -> Optic' k is s a -> Maybe a
^? Prism (Maybe Guild) (Maybe Guild) Guild Guild
forall a b. Prism (Maybe a) (Maybe b) a b
_Just Prism (Maybe Guild) (Maybe Guild) Guild Guild
-> Optic
     A_Lens
     NoIx
     Guild
     Guild
     (SnowflakeMap GuildChannel)
     (SnowflakeMap GuildChannel)
-> Optic
     An_AffineTraversal
     NoIx
     (Maybe Guild)
     (Maybe Guild)
     (SnowflakeMap GuildChannel)
     (SnowflakeMap 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
% Optic
  A_Lens
  NoIx
  Guild
  Guild
  (SnowflakeMap GuildChannel)
  (SnowflakeMap GuildChannel)
#channels Optic
  An_AffineTraversal
  NoIx
  (Maybe Guild)
  (Maybe Guild)
  (SnowflakeMap GuildChannel)
  (SnowflakeMap GuildChannel)
-> Optic
     (IxKind (SnowflakeMap GuildChannel))
     NoIx
     (SnowflakeMap GuildChannel)
     (SnowflakeMap GuildChannel)
     GuildChannel
     GuildChannel
-> Optic' An_AffineTraversal NoIx (Maybe Guild) 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)
-> Optic'
     (IxKind (SnowflakeMap GuildChannel))
     NoIx
     (SnowflakeMap GuildChannel)
     (IxValue (SnowflakeMap GuildChannel))
forall m. Ixed m => Index m -> Optic' (IxKind m) NoIx m (IxValue m)
ix (Snowflake Channel -> Snowflake GuildChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake Channel -> Snowflake GuildChannel)
-> Snowflake Channel -> Snowflake GuildChannel
forall a b. (a -> b) -> a -> b
$ forall b a. HasID b a => a -> Snowflake b
getID @Channel Message
msg)
  Just Channel
channel <- case Maybe GuildChannel
gchan of
    Just GuildChannel
chan -> Maybe Channel -> Sem (Fail : r) (Maybe Channel)
forall a. a -> Sem (Fail : r) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Channel -> Sem (Fail : r) (Maybe Channel))
-> (Channel -> Maybe Channel)
-> Channel
-> Sem (Fail : r) (Maybe Channel)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Channel -> Maybe Channel
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Channel -> Sem (Fail : r) (Maybe Channel))
-> Channel -> Sem (Fail : r) (Maybe Channel)
forall a b. (a -> b) -> a -> b
$ GuildChannel -> Channel
GuildChannel' GuildChannel
chan
    Maybe GuildChannel
Nothing -> DMChannel -> Channel
DMChannel' (DMChannel -> Channel)
-> Sem (Fail : r) (Maybe DMChannel)
-> Sem (Fail : r) (Maybe Channel)
forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<<$>> Snowflake DMChannel -> Sem (Fail : 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 -> Snowflake DMChannel)
-> Snowflake Channel -> Snowflake DMChannel
forall a b. (a -> b) -> a -> b
$ forall b a. HasID b a => a -> Snowflake b
getID @Channel Message
msg)

  FullContext -> Sem (Fail : r) FullContext
forall a. a -> Sem (Fail : r) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FullContext -> Sem (Fail : r) FullContext)
-> FullContext -> Sem (Fail : r) FullContext
forall a b. (a -> b) -> a -> b
$ Message
-> Maybe Guild
-> Maybe Member
-> Channel
-> User
-> Command FullContext
-> Text
-> Text
-> FullContext
FullContext Message
msg Maybe Guild
guild Maybe Member
member Channel
channel User
usr Command FullContext
command Text
prefix Text
unparsed

-- | A lightweight context that doesn't need any cache information
data LightContext = LightContext
  { LightContext -> Message
message :: Message
  -- ^ The message that the command was invoked from
  , LightContext -> Maybe (Snowflake Guild)
guildID :: Maybe (Snowflake Guild)
  -- ^ If the command was sent in a guild, this will be present
  , LightContext -> Snowflake Channel
channelID :: Snowflake Channel
  -- ^ The channel the command was invoked from
  , LightContext -> User
user :: User
  -- ^ The user that invoked the command
  , LightContext -> Maybe Member
member :: Maybe Member
  -- ^ The member that triggered the command.
  --
  -- Note: Only sent if discord sent the member object with the message.
  , LightContext -> Command LightContext
command :: Command LightContext
  -- ^ The command that was invoked
  , LightContext -> Text
prefix :: T.Text
  -- ^ The prefix that was used to invoke the command
  , LightContext -> Text
unparsedParams :: T.Text
  -- ^ The message remaining after consuming the prefix
  }
  deriving (Int -> LightContext -> ShowS
[LightContext] -> ShowS
LightContext -> String
(Int -> LightContext -> ShowS)
-> (LightContext -> String)
-> ([LightContext] -> ShowS)
-> Show LightContext
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LightContext -> ShowS
showsPrec :: Int -> LightContext -> ShowS
$cshow :: LightContext -> String
show :: LightContext -> String
$cshowList :: [LightContext] -> ShowS
showList :: [LightContext] -> ShowS
Show)
  deriving (Int -> LightContext -> Text
Int -> LightContext -> Builder
Int -> LightContext -> Text
[LightContext] -> Text
[LightContext] -> Builder
[LightContext] -> Text
LightContext -> Text
LightContext -> Builder
LightContext -> Text
(Int -> LightContext -> Builder)
-> (LightContext -> Builder)
-> ([LightContext] -> Builder)
-> (Int -> LightContext -> Text)
-> (LightContext -> Text)
-> ([LightContext] -> Text)
-> (Int -> LightContext -> Text)
-> (LightContext -> Text)
-> ([LightContext] -> Text)
-> TextShow LightContext
forall a.
(Int -> a -> Builder)
-> (a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> TextShow a
$cshowbPrec :: Int -> LightContext -> Builder
showbPrec :: Int -> LightContext -> Builder
$cshowb :: LightContext -> Builder
showb :: LightContext -> Builder
$cshowbList :: [LightContext] -> Builder
showbList :: [LightContext] -> Builder
$cshowtPrec :: Int -> LightContext -> Text
showtPrec :: Int -> LightContext -> Text
$cshowt :: LightContext -> Text
showt :: LightContext -> Text
$cshowtList :: [LightContext] -> Text
showtList :: [LightContext] -> Text
$cshowtlPrec :: Int -> LightContext -> Text
showtlPrec :: Int -> LightContext -> Text
$cshowtl :: LightContext -> Text
showtl :: LightContext -> Text
$cshowtlList :: [LightContext] -> Text
showtlList :: [LightContext] -> Text
TextShow.TextShow) via TextShow.FromStringShow LightContext
  deriving (HasID Channel) via HasIDField "channelID" LightContext
  deriving (HasID Message) via HasIDField "message" LightContext
  deriving (HasID User) via HasIDField "user" LightContext

$(makeFieldLabelsNoPrefix ''LightContext)

instance CC.CommandContext IO LightContext () where
  ctxPrefix :: LightContext -> Text
ctxPrefix = (LightContext -> Optic' A_Lens NoIx LightContext Text -> Text
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx LightContext Text
#prefix)
  ctxCommand :: LightContext -> Command LightContext
ctxCommand = (LightContext
-> Optic' A_Lens NoIx LightContext (Command LightContext)
-> Command LightContext
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx LightContext (Command LightContext)
#command)
  ctxUnparsedParams :: LightContext -> Text
ctxUnparsedParams = (LightContext -> Optic' A_Lens NoIx LightContext Text -> Text
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx LightContext Text
#unparsedParams)

instance CalamityCommandContext LightContext where
  ctxChannelID :: LightContext -> Snowflake Channel
ctxChannelID = (LightContext
-> Optic' A_Lens NoIx LightContext (Snowflake Channel)
-> Snowflake Channel
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx LightContext (Snowflake Channel)
#channelID)
  ctxGuildID :: LightContext -> Maybe (Snowflake Guild)
ctxGuildID = (LightContext
-> Optic' A_Lens NoIx LightContext (Maybe (Snowflake Guild))
-> Maybe (Snowflake Guild)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx LightContext (Maybe (Snowflake Guild))
#guildID)
  ctxUserID :: LightContext -> Snowflake User
ctxUserID = (LightContext
-> Optic' A_Lens NoIx LightContext (Snowflake User)
-> Snowflake User
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic A_Lens NoIx LightContext LightContext User User
#user Optic A_Lens NoIx LightContext LightContext User User
-> Optic A_Lens NoIx User User (Snowflake User) (Snowflake User)
-> Optic' A_Lens NoIx LightContext (Snowflake User)
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
% Optic A_Lens NoIx User User (Snowflake User) (Snowflake User)
#id)
  ctxMessage :: LightContext -> Message
ctxMessage = (LightContext -> Optic' A_Lens NoIx LightContext Message -> Message
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx LightContext Message
#message)

instance Tellable LightContext where
  getChannel :: forall (r :: EffectRow).
(BotC r, Member (Error RestError) r) =>
LightContext -> Sem r (Snowflake Channel)
getChannel = Snowflake Channel -> Sem r (Snowflake Channel)
forall a. a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Snowflake Channel -> Sem r (Snowflake Channel))
-> (LightContext -> Snowflake Channel)
-> LightContext
-> Sem r (Snowflake Channel)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LightContext -> Snowflake Channel
forall c. CalamityCommandContext c => c -> Snowflake Channel
ctxChannelID

useLightContext :: P.Sem (CC.ConstructContext (Message, User, Maybe Member) LightContext IO () ': r) a -> P.Sem r a
useLightContext :: forall (r :: EffectRow) a.
Sem
  (ConstructContext (Message, User, Maybe Member) LightContext IO ()
     : r)
  a
-> Sem r a
useLightContext =
  (forall (rInitial :: EffectRow) x.
 ConstructContext
   (Message, User, Maybe Member) LightContext IO () (Sem rInitial) x
 -> Sem r x)
-> Sem
     (ConstructContext (Message, User, Maybe Member) LightContext IO ()
        : r)
     a
-> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
P.interpret
    ( \case
        CC.ConstructContext (Text
pre, Command LightContext
cmd, Text
up) (Message
msg, User
usr, Maybe Member
mem) ->
          x -> Sem r x
forall a. a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (x -> Sem r x) -> (LightContext -> x) -> LightContext -> Sem r x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LightContext -> x
LightContext -> Maybe LightContext
forall a. a -> Maybe a
Just (LightContext -> Sem r x) -> LightContext -> Sem r x
forall a b. (a -> b) -> a -> b
$ Message
-> Maybe (Snowflake Guild)
-> Snowflake Channel
-> User
-> Maybe Member
-> Command LightContext
-> Text
-> Text
-> LightContext
LightContext Message
msg (Message
msg Message
-> Optic' A_Lens NoIx Message (Maybe (Snowflake Guild))
-> Maybe (Snowflake Guild)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx Message (Maybe (Snowflake Guild))
#guildID) (Message
msg Message
-> Optic' A_Lens NoIx Message (Snowflake Channel)
-> Snowflake Channel
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx Message (Snowflake Channel)
#channelID) User
usr Maybe Member
mem Command LightContext
cmd Text
pre Text
up
    )