{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- | Provides actions for Channel API interactions
module Discord.Internal.Rest.Emoji
  ( EmojiRequest (..),
    ModifyGuildEmojiOpts (..),
    parseEmojiImage,
    parseStickerImage,
    StickerRequest (..),
    CreateGuildStickerOpts (..),
    EditGuildStickerOpts (..)
  )
where

import Data.Aeson
import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as B64
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Discord.Internal.Rest.Prelude
import Discord.Internal.Types
import Network.HTTP.Req ((/:), (/~))
import qualified Network.HTTP.Req as R

instance Request (EmojiRequest a) where
  majorRoute :: EmojiRequest a -> String
majorRoute = forall a. EmojiRequest a -> String
emojiMajorRoute
  jsonRequest :: EmojiRequest a -> JsonRequest
jsonRequest = forall a. EmojiRequest a -> JsonRequest
emojiJsonRequest

-- | Data constructor for requests. See <https://discord.com/developers/docs/resources/ API>
data EmojiRequest a where
  -- | List of emoji objects for the given guild. Requires MANAGE_EMOJIS permission.
  ListGuildEmojis :: GuildId -> EmojiRequest [Emoji]
  -- | Emoji object for the given guild and emoji ID
  GetGuildEmoji :: GuildId -> EmojiId -> EmojiRequest Emoji
  -- | Create a new guild emoji (static&animated). Requires MANAGE_EMOJIS permission.
  CreateGuildEmoji :: GuildId -> T.Text -> Base64Image Emoji -> EmojiRequest Emoji
  -- | Requires MANAGE_EMOJIS permission
  ModifyGuildEmoji :: GuildId -> EmojiId -> ModifyGuildEmojiOpts -> EmojiRequest Emoji
  -- | Requires MANAGE_EMOJIS permission
  DeleteGuildEmoji :: GuildId -> EmojiId -> EmojiRequest ()

data ModifyGuildEmojiOpts = ModifyGuildEmojiOpts
  { ModifyGuildEmojiOpts -> Text
modifyGuildEmojiName :: T.Text,
    ModifyGuildEmojiOpts -> [RoleId]
modifyGuildEmojiRoles :: [RoleId]
  }
  deriving (Int -> ModifyGuildEmojiOpts -> ShowS
[ModifyGuildEmojiOpts] -> ShowS
ModifyGuildEmojiOpts -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ModifyGuildEmojiOpts] -> ShowS
$cshowList :: [ModifyGuildEmojiOpts] -> ShowS
show :: ModifyGuildEmojiOpts -> String
$cshow :: ModifyGuildEmojiOpts -> String
showsPrec :: Int -> ModifyGuildEmojiOpts -> ShowS
$cshowsPrec :: Int -> ModifyGuildEmojiOpts -> ShowS
Show, ReadPrec [ModifyGuildEmojiOpts]
ReadPrec ModifyGuildEmojiOpts
Int -> ReadS ModifyGuildEmojiOpts
ReadS [ModifyGuildEmojiOpts]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ModifyGuildEmojiOpts]
$creadListPrec :: ReadPrec [ModifyGuildEmojiOpts]
readPrec :: ReadPrec ModifyGuildEmojiOpts
$creadPrec :: ReadPrec ModifyGuildEmojiOpts
readList :: ReadS [ModifyGuildEmojiOpts]
$creadList :: ReadS [ModifyGuildEmojiOpts]
readsPrec :: Int -> ReadS ModifyGuildEmojiOpts
$creadsPrec :: Int -> ReadS ModifyGuildEmojiOpts
Read, ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
$c/= :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
== :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
$c== :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
Eq, Eq ModifyGuildEmojiOpts
ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Ordering
ModifyGuildEmojiOpts
-> ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ModifyGuildEmojiOpts
-> ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts
$cmin :: ModifyGuildEmojiOpts
-> ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts
max :: ModifyGuildEmojiOpts
-> ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts
$cmax :: ModifyGuildEmojiOpts
-> ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts
>= :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
$c>= :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
> :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
$c> :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
<= :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
$c<= :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
< :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
$c< :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Bool
compare :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Ordering
$ccompare :: ModifyGuildEmojiOpts -> ModifyGuildEmojiOpts -> Ordering
Ord)

instance ToJSON ModifyGuildEmojiOpts where
  toJSON :: ModifyGuildEmojiOpts -> Value
toJSON (ModifyGuildEmojiOpts Text
name [RoleId]
roles) =
    [Pair] -> Value
object [Key
"name" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
name, Key
"roles" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [RoleId]
roles]


-- | @parseEmojiImage bs@ will attempt to convert the given image bytestring @bs@
-- to the base64 format expected by the Discord API. It may return Left with an
-- error reason if either the bytestring is too large, or if the image format
-- could not be predetermined from the opening few bytes. This function does
-- /not/ validate the rest of the image, nor check that its dimensions are
-- 128x128 as required by Discord. This is up to the library user to check.
--
-- This function accepts all file types accepted by 'getMimeType'.
parseEmojiImage :: B.ByteString -> Either T.Text (Base64Image Emoji)
parseEmojiImage :: ByteString -> Either Text (Base64Image Emoji)
parseEmojiImage ByteString
bs
  | ByteString -> Int
B.length ByteString
bs forall a. Ord a => a -> a -> Bool
> Int
256000        = forall a b. a -> Either a b
Left Text
"Cannot create emoji - File is larger than 256kb"
  | Just Text
mime <- ByteString -> Maybe Text
getMimeType ByteString
bs = forall a b. b -> Either a b
Right (forall a. Text -> Text -> Base64Image a
Base64Image Text
mime (ByteString -> Text
TE.decodeUtf8 (ByteString -> ByteString
B64.encode ByteString
bs)))
  | Bool
otherwise                   = forall a b. a -> Either a b
Left Text
"Unsupported image format provided"

emojiMajorRoute :: EmojiRequest a -> String
emojiMajorRoute :: forall a. EmojiRequest a -> String
emojiMajorRoute EmojiRequest a
c = case EmojiRequest a
c of
  (ListGuildEmojis GuildId
g) -> String
"emoji " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
g
  (GetGuildEmoji GuildId
g EmojiId
_) -> String
"emoji " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
g
  (CreateGuildEmoji GuildId
g Text
_ Base64Image Emoji
_) -> String
"emoji " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
g
  (ModifyGuildEmoji GuildId
g EmojiId
_ ModifyGuildEmojiOpts
_) -> String
"emoji " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
g
  (DeleteGuildEmoji GuildId
g EmojiId
_) -> String
"emoji " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
g

guilds :: R.Url 'R.Https
guilds :: Url 'Https
guilds = Url 'Https
baseUrl forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"guilds"

emojiJsonRequest :: EmojiRequest r -> JsonRequest
emojiJsonRequest :: forall a. EmojiRequest a -> JsonRequest
emojiJsonRequest EmojiRequest r
c = case EmojiRequest r
c of
  (ListGuildEmojis GuildId
g) -> Url 'Https -> Option 'Https -> JsonRequest
Get (Url 'Https
guilds forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ GuildId
g forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"emojis") forall a. Monoid a => a
mempty
  (GetGuildEmoji GuildId
g EmojiId
e) -> Url 'Https -> Option 'Https -> JsonRequest
Get (Url 'Https
guilds forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ GuildId
g forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"emojis" forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ EmojiId
e) forall a. Monoid a => a
mempty
  (CreateGuildEmoji GuildId
g Text
name Base64Image Emoji
b64im) ->
    forall a.
HttpBody a =>
Url 'Https -> RestIO a -> Option 'Https -> JsonRequest
Post
      (Url 'Https
guilds forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ GuildId
g forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"emojis")
      ( forall (f :: * -> *) a. Applicative f => a -> f a
pure
          ( forall a. a -> ReqBodyJson a
R.ReqBodyJson
              ( [Pair] -> Value
object
                  [ Key
"name" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
name,
                    Key
"image" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Base64Image Emoji
b64im
                    -- todo , "roles" .= ...
                  ]
              )
          )
      )
      forall a. Monoid a => a
mempty
  (ModifyGuildEmoji GuildId
g EmojiId
e ModifyGuildEmojiOpts
o) ->
    forall a.
HttpBody a =>
Url 'Https -> RestIO a -> Option 'Https -> JsonRequest
Patch
      (Url 'Https
guilds forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ GuildId
g forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"emojis" forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ EmojiId
e)
      (forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> ReqBodyJson a
R.ReqBodyJson ModifyGuildEmojiOpts
o))
      forall a. Monoid a => a
mempty
  (DeleteGuildEmoji GuildId
g EmojiId
e) -> Url 'Https -> Option 'Https -> JsonRequest
Delete (Url 'Https
guilds forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ GuildId
g forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"emojis" forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ EmojiId
e) forall a. Monoid a => a
mempty

-- | @parseStickerImage bs@ accepts PNG, APNG, or Lottie JSON bytestring @bs@ and
-- will attempt to convert it to the base64 format expected by the Discord API.
-- It may return Left with an error reason if the image format is unexpected.
-- This function does /not/ validate the contents of the image, this is up to
-- the library user to check.
parseStickerImage :: B.ByteString -> Either T.Text (Base64Image Sticker)
parseStickerImage :: ByteString -> Either Text (Base64Image Sticker)
parseStickerImage ByteString
bs
  | ByteString -> Int
B.length ByteString
bs forall a. Ord a => a -> a -> Bool
> Int
512000
  = forall a b. a -> Either a b
Left Text
"Cannot create sticker - File is larger than 512kb"
  | Just Text
"image/png" <- ByteString -> Maybe Text
getMimeType ByteString
bs
  = forall a b. b -> Either a b
Right (forall a. Text -> Text -> Base64Image a
Base64Image Text
"image/png" (ByteString -> Text
TE.decodeUtf8 (ByteString -> ByteString
B64.encode ByteString
bs)))
  | Bool -> Bool
not (ByteString -> Bool
B.null ByteString
bs) Bool -> Bool -> Bool
&& HasCallStack => ByteString -> Word8
B.head ByteString
bs forall a. Eq a => a -> a -> Bool
== Word8
0x7b -- '{'
  = forall a b. b -> Either a b
Right (forall a. Text -> Text -> Base64Image a
Base64Image Text
"application/json" (ByteString -> Text
TE.decodeUtf8 (ByteString -> ByteString
B64.encode ByteString
bs)))
  | Bool
otherwise
  = forall a b. a -> Either a b
Left Text
"Unsupported image format provided"

-- | Options for `CreateGuildSticker`
data CreateGuildStickerOpts = CreateGuildStickerOpts
  { CreateGuildStickerOpts -> Text
guildStickerName :: T.Text,
    CreateGuildStickerOpts -> Text
guildStickerDescription :: T.Text,
    CreateGuildStickerOpts -> [Text]
guildStickerTags :: [T.Text],
    CreateGuildStickerOpts -> Base64Image Sticker
guildStickerFile :: Base64Image Sticker
  }
  deriving (Int -> CreateGuildStickerOpts -> ShowS
[CreateGuildStickerOpts] -> ShowS
CreateGuildStickerOpts -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CreateGuildStickerOpts] -> ShowS
$cshowList :: [CreateGuildStickerOpts] -> ShowS
show :: CreateGuildStickerOpts -> String
$cshow :: CreateGuildStickerOpts -> String
showsPrec :: Int -> CreateGuildStickerOpts -> ShowS
$cshowsPrec :: Int -> CreateGuildStickerOpts -> ShowS
Show, ReadPrec [CreateGuildStickerOpts]
ReadPrec CreateGuildStickerOpts
Int -> ReadS CreateGuildStickerOpts
ReadS [CreateGuildStickerOpts]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CreateGuildStickerOpts]
$creadListPrec :: ReadPrec [CreateGuildStickerOpts]
readPrec :: ReadPrec CreateGuildStickerOpts
$creadPrec :: ReadPrec CreateGuildStickerOpts
readList :: ReadS [CreateGuildStickerOpts]
$creadList :: ReadS [CreateGuildStickerOpts]
readsPrec :: Int -> ReadS CreateGuildStickerOpts
$creadsPrec :: Int -> ReadS CreateGuildStickerOpts
Read, CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
$c/= :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
== :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
$c== :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
Eq, Eq CreateGuildStickerOpts
CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
CreateGuildStickerOpts -> CreateGuildStickerOpts -> Ordering
CreateGuildStickerOpts
-> CreateGuildStickerOpts -> CreateGuildStickerOpts
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CreateGuildStickerOpts
-> CreateGuildStickerOpts -> CreateGuildStickerOpts
$cmin :: CreateGuildStickerOpts
-> CreateGuildStickerOpts -> CreateGuildStickerOpts
max :: CreateGuildStickerOpts
-> CreateGuildStickerOpts -> CreateGuildStickerOpts
$cmax :: CreateGuildStickerOpts
-> CreateGuildStickerOpts -> CreateGuildStickerOpts
>= :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
$c>= :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
> :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
$c> :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
<= :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
$c<= :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
< :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
$c< :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Bool
compare :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Ordering
$ccompare :: CreateGuildStickerOpts -> CreateGuildStickerOpts -> Ordering
Ord)

instance ToJSON CreateGuildStickerOpts where
  toJSON :: CreateGuildStickerOpts -> Value
toJSON (CreateGuildStickerOpts Text
name Text
desc [Text]
tags Base64Image Sticker
b64im) =
    [Pair] -> Value
object
      [ (Key
"name", forall a. ToJSON a => a -> Value
toJSON Text
name),
        (Key
"description", forall a. ToJSON a => a -> Value
toJSON Text
desc),
        (Key
"tags", forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate Text
"," [Text]
tags),
        (Key
"file", forall a. ToJSON a => a -> Value
toJSON Base64Image Sticker
b64im)
      ]

-- | Options for `ModifyGuildSticker`
data EditGuildStickerOpts = EditGuildStickerOpts
  { EditGuildStickerOpts -> Maybe Text
editGuildStickerName :: Maybe T.Text,
    EditGuildStickerOpts -> Maybe Text
editGuildStickerDescription :: Maybe T.Text,
    EditGuildStickerOpts -> Maybe [Text]
editGuildStickerTags :: Maybe [T.Text]
  }
  deriving (Int -> EditGuildStickerOpts -> ShowS
[EditGuildStickerOpts] -> ShowS
EditGuildStickerOpts -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EditGuildStickerOpts] -> ShowS
$cshowList :: [EditGuildStickerOpts] -> ShowS
show :: EditGuildStickerOpts -> String
$cshow :: EditGuildStickerOpts -> String
showsPrec :: Int -> EditGuildStickerOpts -> ShowS
$cshowsPrec :: Int -> EditGuildStickerOpts -> ShowS
Show, ReadPrec [EditGuildStickerOpts]
ReadPrec EditGuildStickerOpts
Int -> ReadS EditGuildStickerOpts
ReadS [EditGuildStickerOpts]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [EditGuildStickerOpts]
$creadListPrec :: ReadPrec [EditGuildStickerOpts]
readPrec :: ReadPrec EditGuildStickerOpts
$creadPrec :: ReadPrec EditGuildStickerOpts
readList :: ReadS [EditGuildStickerOpts]
$creadList :: ReadS [EditGuildStickerOpts]
readsPrec :: Int -> ReadS EditGuildStickerOpts
$creadsPrec :: Int -> ReadS EditGuildStickerOpts
Read, EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
$c/= :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
== :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
$c== :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
Eq, Eq EditGuildStickerOpts
EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
EditGuildStickerOpts -> EditGuildStickerOpts -> Ordering
EditGuildStickerOpts
-> EditGuildStickerOpts -> EditGuildStickerOpts
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EditGuildStickerOpts
-> EditGuildStickerOpts -> EditGuildStickerOpts
$cmin :: EditGuildStickerOpts
-> EditGuildStickerOpts -> EditGuildStickerOpts
max :: EditGuildStickerOpts
-> EditGuildStickerOpts -> EditGuildStickerOpts
$cmax :: EditGuildStickerOpts
-> EditGuildStickerOpts -> EditGuildStickerOpts
>= :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
$c>= :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
> :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
$c> :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
<= :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
$c<= :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
< :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
$c< :: EditGuildStickerOpts -> EditGuildStickerOpts -> Bool
compare :: EditGuildStickerOpts -> EditGuildStickerOpts -> Ordering
$ccompare :: EditGuildStickerOpts -> EditGuildStickerOpts -> Ordering
Ord)

instance ToJSON EditGuildStickerOpts where
  toJSON :: EditGuildStickerOpts -> Value
toJSON EditGuildStickerOpts {Maybe [Text]
Maybe Text
editGuildStickerTags :: Maybe [Text]
editGuildStickerDescription :: Maybe Text
editGuildStickerName :: Maybe Text
editGuildStickerTags :: EditGuildStickerOpts -> Maybe [Text]
editGuildStickerDescription :: EditGuildStickerOpts -> Maybe Text
editGuildStickerName :: EditGuildStickerOpts -> Maybe Text
..} =
    [Maybe Pair] -> Value
objectFromMaybes
      [ Key
"name" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Text
editGuildStickerName,
        Key
"description" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Text
editGuildStickerDescription,
        Key
"tags" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> [Text] -> Text
T.intercalate Text
",") Maybe [Text]
editGuildStickerTags
      ]

instance Request (StickerRequest a) where
  majorRoute :: StickerRequest a -> String
majorRoute = forall a. StickerRequest a -> String
stickerMajorRoute
  jsonRequest :: StickerRequest a -> JsonRequest
jsonRequest = forall a. StickerRequest a -> JsonRequest
stickerJsonRequest

-- | Data constructor for requests. See <https://discord.com/developers/docs/resources/ API>
--
-- Be warned that these are untested due to not having a spare server with 
-- boosts. Functionality is at your own risk.
data StickerRequest a where
  -- | Returns a sticker object for the given sticker ID.
  GetSticker :: StickerId -> StickerRequest Sticker
  -- | Returns the list of sticker packs available to Nitro subscribers.
  ListNitroStickerPacks :: StickerRequest [StickerPack]
  -- | Returns an array of sticker objects for the given guild.
  ListGuildStickers :: GuildId -> StickerRequest [Sticker]
  -- | Returns a sticker object for the given guild and sticker ID.
  GetGuildSticker :: GuildId -> StickerId -> StickerRequest Sticker
  -- | Create a new sticker for the guild.
  CreateGuildSticker :: GuildId -> CreateGuildStickerOpts -> StickerRequest Sticker
  -- | Modify a sticker for a guild.
  ModifyGuildSticker :: GuildId -> StickerId -> EditGuildStickerOpts -> StickerRequest Sticker
  -- | Delete a guild sticker
  DeleteGuildSticker :: GuildId -> StickerId -> StickerRequest ()

stickerMajorRoute :: StickerRequest a -> String
stickerMajorRoute :: forall a. StickerRequest a -> String
stickerMajorRoute = \case
  GetSticker StickerId
gid -> String
"sticker " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show StickerId
gid
  StickerRequest a
ListNitroStickerPacks -> String
"sticker"
  ListGuildStickers GuildId
gid -> String
"sticker " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
gid
  GetGuildSticker GuildId
gid StickerId
_ -> String
"sticker " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
gid
  CreateGuildSticker GuildId
gid CreateGuildStickerOpts
_ -> String
"sticker " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
gid
  ModifyGuildSticker GuildId
gid StickerId
_ EditGuildStickerOpts
_ -> String
"sticker " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
gid
  DeleteGuildSticker GuildId
gid StickerId
_ -> String
"sticker " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show GuildId
gid

stickerJsonRequest :: StickerRequest a -> JsonRequest
stickerJsonRequest :: forall a. StickerRequest a -> JsonRequest
stickerJsonRequest = \case
  GetSticker StickerId
gid -> Url 'Https -> Option 'Https -> JsonRequest
Get (Url 'Https
baseUrl forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"stickers" forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ StickerId
gid) forall a. Monoid a => a
mempty
  StickerRequest a
ListNitroStickerPacks -> Url 'Https -> Option 'Https -> JsonRequest
Get (Url 'Https
baseUrl forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"sticker-packs") forall a. Monoid a => a
mempty
  ListGuildStickers GuildId
gid -> Url 'Https -> Option 'Https -> JsonRequest
Get (forall {a}. ToHttpApiData a => a -> Url 'Https
stickersGuild GuildId
gid) forall a. Monoid a => a
mempty
  GetGuildSticker GuildId
gid StickerId
sid -> Url 'Https -> Option 'Https -> JsonRequest
Get (forall {a}. ToHttpApiData a => a -> Url 'Https
stickersGuild GuildId
gid forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ StickerId
sid) forall a. Monoid a => a
mempty
  CreateGuildSticker GuildId
gid CreateGuildStickerOpts
cgso -> forall a.
HttpBody a =>
Url 'Https -> RestIO a -> Option 'Https -> JsonRequest
Post (forall {a}. ToHttpApiData a => a -> Url 'Https
stickersGuild GuildId
gid) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> ReqBodyJson a
R.ReqBodyJson forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> Value
toJSON CreateGuildStickerOpts
cgso) forall a. Monoid a => a
mempty
  ModifyGuildSticker GuildId
gid StickerId
sid EditGuildStickerOpts
egso -> forall a.
HttpBody a =>
Url 'Https -> RestIO a -> Option 'Https -> JsonRequest
Patch (forall {a}. ToHttpApiData a => a -> Url 'Https
stickersGuild GuildId
gid forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ StickerId
sid) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> ReqBodyJson a
R.ReqBodyJson EditGuildStickerOpts
egso) forall a. Monoid a => a
mempty
  DeleteGuildSticker GuildId
gid StickerId
sid -> Url 'Https -> Option 'Https -> JsonRequest
Delete (forall {a}. ToHttpApiData a => a -> Url 'Https
stickersGuild GuildId
gid forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ StickerId
sid) forall a. Monoid a => a
mempty
  where
    stickersGuild :: a -> Url 'Https
stickersGuild a
gid = Url 'Https
baseUrl forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"guilds" forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ a
gid forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"stickers"