{-# LANGUAGE TemplateHaskell #-}

-- | Guild roles
module Calamity.Types.Model.Guild.Role (
  Role (..),
  RoleIcon (..),
) where

import Calamity.Internal.IntColour
import Calamity.Internal.Utils
import Calamity.Types.CDNAsset (CDNAsset (..))
import Calamity.Types.Model.Guild.Emoji
import Calamity.Types.Model.Guild.Permissions
import Calamity.Types.Snowflake
import Calamity.Utils.CDNUrl (assetHashFile, cdnURL)
import Data.Aeson ((.:), (.:?))
import Data.Aeson qualified as Aeson
import Data.Colour
import Data.Text (Text)
import Data.Text qualified as T
import Network.HTTP.Req ((/:), (/~))
import Optics.TH
import TextShow qualified

data RoleIcon = RoleIcon
  { RoleIcon -> Snowflake Role
roleID :: Snowflake Role
  , RoleIcon -> Text
hash :: T.Text
  }
  deriving (Int -> RoleIcon -> ShowS
[RoleIcon] -> ShowS
RoleIcon -> String
(Int -> RoleIcon -> ShowS)
-> (RoleIcon -> String) -> ([RoleIcon] -> ShowS) -> Show RoleIcon
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RoleIcon -> ShowS
showsPrec :: Int -> RoleIcon -> ShowS
$cshow :: RoleIcon -> String
show :: RoleIcon -> String
$cshowList :: [RoleIcon] -> ShowS
showList :: [RoleIcon] -> ShowS
Show, RoleIcon -> RoleIcon -> Bool
(RoleIcon -> RoleIcon -> Bool)
-> (RoleIcon -> RoleIcon -> Bool) -> Eq RoleIcon
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RoleIcon -> RoleIcon -> Bool
== :: RoleIcon -> RoleIcon -> Bool
$c/= :: RoleIcon -> RoleIcon -> Bool
/= :: RoleIcon -> RoleIcon -> Bool
Eq)

instance CDNAsset RoleIcon where
  assetURL :: RoleIcon -> Url 'Https
assetURL RoleIcon {Text
$sel:hash:RoleIcon :: RoleIcon -> Text
hash :: Text
hash, Snowflake Role
$sel:roleID:RoleIcon :: RoleIcon -> Snowflake Role
roleID :: Snowflake Role
roleID} =
    Url 'Https
cdnURL Url 'Https -> Text -> Url 'Https
forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text
"icons" Url 'Https -> Snowflake Role -> Url 'Https
forall a (scheme :: Scheme).
ToHttpApiData a =>
Url scheme -> a -> Url scheme
/~ Snowflake Role
roleID Url 'Https -> Text -> Url 'Https
forall (scheme :: Scheme). Url scheme -> Text -> Url scheme
/: Text -> Text
assetHashFile Text
hash

data Role = Role
  { Role -> Snowflake Role
id :: Snowflake Role
  , Role -> Text
name :: Text
  , Role -> Colour Double
color :: Colour Double
  , Role -> Bool
hoist :: Bool
  , Role -> Maybe RoleIcon
icon :: Maybe RoleIcon
  , Role -> Maybe RawEmoji
emoji :: Maybe RawEmoji
  , Role -> Int
position :: Int
  , Role -> Permissions
permissions :: Permissions
  , Role -> Bool
managed :: Bool
  , Role -> Bool
mentionable :: Bool
  }
  deriving (Role -> Role -> Bool
(Role -> Role -> Bool) -> (Role -> Role -> Bool) -> Eq Role
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Role -> Role -> Bool
== :: Role -> Role -> Bool
$c/= :: Role -> Role -> Bool
/= :: Role -> Role -> Bool
Eq, Int -> Role -> ShowS
[Role] -> ShowS
Role -> String
(Int -> Role -> ShowS)
-> (Role -> String) -> ([Role] -> ShowS) -> Show Role
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Role -> ShowS
showsPrec :: Int -> Role -> ShowS
$cshow :: Role -> String
show :: Role -> String
$cshowList :: [Role] -> ShowS
showList :: [Role] -> ShowS
Show)
  deriving (Int -> Role -> Text
Int -> Role -> Builder
Int -> Role -> Text
[Role] -> Text
[Role] -> Builder
[Role] -> Text
Role -> Text
Role -> Builder
Role -> Text
(Int -> Role -> Builder)
-> (Role -> Builder)
-> ([Role] -> Builder)
-> (Int -> Role -> Text)
-> (Role -> Text)
-> ([Role] -> Text)
-> (Int -> Role -> Text)
-> (Role -> Text)
-> ([Role] -> Text)
-> TextShow Role
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 -> Role -> Builder
showbPrec :: Int -> Role -> Builder
$cshowb :: Role -> Builder
showb :: Role -> Builder
$cshowbList :: [Role] -> Builder
showbList :: [Role] -> Builder
$cshowtPrec :: Int -> Role -> Text
showtPrec :: Int -> Role -> Text
$cshowt :: Role -> Text
showt :: Role -> Text
$cshowtList :: [Role] -> Text
showtList :: [Role] -> Text
$cshowtlPrec :: Int -> Role -> Text
showtlPrec :: Int -> Role -> Text
$cshowtl :: Role -> Text
showtl :: Role -> Text
$cshowtlList :: [Role] -> Text
showtlList :: [Role] -> Text
TextShow.TextShow) via TextShow.FromStringShow Role
  deriving (HasID Role) via HasIDField "id" Role
  deriving ([Role] -> Value
[Role] -> Encoding
Role -> Value
Role -> Encoding
(Role -> Value)
-> (Role -> Encoding)
-> ([Role] -> Value)
-> ([Role] -> Encoding)
-> ToJSON Role
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: Role -> Value
toJSON :: Role -> Value
$ctoEncoding :: Role -> Encoding
toEncoding :: Role -> Encoding
$ctoJSONList :: [Role] -> Value
toJSONList :: [Role] -> Value
$ctoEncodingList :: [Role] -> Encoding
toEncodingList :: [Role] -> Encoding
Aeson.ToJSON) via CalamityToJSON Role

instance CalamityToJSON' Role where
  toPairs :: forall kv. KeyValue kv => Role -> [Maybe kv]
toPairs Role {Bool
Int
Maybe RoleIcon
Maybe RawEmoji
Text
Colour Double
Permissions
Snowflake Role
$sel:id:Role :: Role -> Snowflake Role
$sel:name:Role :: Role -> Text
$sel:color:Role :: Role -> Colour Double
$sel:hoist:Role :: Role -> Bool
$sel:icon:Role :: Role -> Maybe RoleIcon
$sel:emoji:Role :: Role -> Maybe RawEmoji
$sel:position:Role :: Role -> Int
$sel:permissions:Role :: Role -> Permissions
$sel:managed:Role :: Role -> Bool
$sel:mentionable:Role :: Role -> Bool
id :: Snowflake Role
name :: Text
color :: Colour Double
hoist :: Bool
icon :: Maybe RoleIcon
emoji :: Maybe RawEmoji
position :: Int
permissions :: Permissions
managed :: Bool
mentionable :: Bool
..} =
    [ Key
"id" Key -> Snowflake Role -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Snowflake Role
id
    , Key
"name" Key -> Text -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Text
name
    , Key
"color" Key -> IntColour -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Colour Double -> IntColour
IntColour Colour Double
color
    , Key
"position" Key -> Int -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Int
position
    , Key
"permissions" Key -> Permissions -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Permissions
permissions
    , Key
"managed" Key -> Bool -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Bool
managed
    , Key
"mentionable" Key -> Bool -> Maybe kv
forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Bool
mentionable
    ]

instance Aeson.FromJSON Role where
  parseJSON :: Value -> Parser Role
parseJSON = String -> (Object -> Parser Role) -> Value -> Parser Role
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Role" ((Object -> Parser Role) -> Value -> Parser Role)
-> (Object -> Parser Role) -> Value -> Parser Role
forall a b. (a -> b) -> a -> b
$ \Object
v -> do
    Snowflake Role
id <- Object
v Object -> Key -> Parser (Snowflake Role)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
    Maybe RoleIcon
icon <- (Snowflake Role -> Text -> RoleIcon
RoleIcon Snowflake Role
id (Text -> RoleIcon) -> Maybe Text -> Maybe RoleIcon
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Maybe Text -> Maybe RoleIcon)
-> Parser (Maybe Text) -> Parser (Maybe RoleIcon)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"icon"
    Maybe RawEmoji
emoji <- (Text -> RawEmoji
UnicodeEmoji (Text -> RawEmoji) -> Maybe Text -> Maybe RawEmoji
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Maybe Text -> Maybe RawEmoji)
-> Parser (Maybe Text) -> Parser (Maybe RawEmoji)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"unicode_emoji"

    Snowflake Role
-> Text
-> Colour Double
-> Bool
-> Maybe RoleIcon
-> Maybe RawEmoji
-> Int
-> Permissions
-> Bool
-> Bool
-> Role
Role
      (Snowflake Role
 -> Text
 -> Colour Double
 -> Bool
 -> Maybe RoleIcon
 -> Maybe RawEmoji
 -> Int
 -> Permissions
 -> Bool
 -> Bool
 -> Role)
-> Parser (Snowflake Role)
-> Parser
     (Text
      -> Colour Double
      -> Bool
      -> Maybe RoleIcon
      -> Maybe RawEmoji
      -> Int
      -> Permissions
      -> Bool
      -> Bool
      -> Role)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Snowflake Role -> Parser (Snowflake Role)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Snowflake Role
id
      Parser
  (Text
   -> Colour Double
   -> Bool
   -> Maybe RoleIcon
   -> Maybe RawEmoji
   -> Int
   -> Permissions
   -> Bool
   -> Bool
   -> Role)
-> Parser Text
-> Parser
     (Colour Double
      -> Bool
      -> Maybe RoleIcon
      -> Maybe RawEmoji
      -> Int
      -> Permissions
      -> Bool
      -> Bool
      -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name"
      Parser
  (Colour Double
   -> Bool
   -> Maybe RoleIcon
   -> Maybe RawEmoji
   -> Int
   -> Permissions
   -> Bool
   -> Bool
   -> Role)
-> Parser (Colour Double)
-> Parser
     (Bool
      -> Maybe RoleIcon
      -> Maybe RawEmoji
      -> Int
      -> Permissions
      -> Bool
      -> Bool
      -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (IntColour -> Colour Double
fromIntColour (IntColour -> Colour Double)
-> Parser IntColour -> Parser (Colour Double)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser IntColour
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"color")
      Parser
  (Bool
   -> Maybe RoleIcon
   -> Maybe RawEmoji
   -> Int
   -> Permissions
   -> Bool
   -> Bool
   -> Role)
-> Parser Bool
-> Parser
     (Maybe RoleIcon
      -> Maybe RawEmoji -> Int -> Permissions -> Bool -> Bool -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"hoist"
      Parser
  (Maybe RoleIcon
   -> Maybe RawEmoji -> Int -> Permissions -> Bool -> Bool -> Role)
-> Parser (Maybe RoleIcon)
-> Parser
     (Maybe RawEmoji -> Int -> Permissions -> Bool -> Bool -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe RoleIcon -> Parser (Maybe RoleIcon)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe RoleIcon
icon
      Parser
  (Maybe RawEmoji -> Int -> Permissions -> Bool -> Bool -> Role)
-> Parser (Maybe RawEmoji)
-> Parser (Int -> Permissions -> Bool -> Bool -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe RawEmoji -> Parser (Maybe RawEmoji)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe RawEmoji
emoji
      Parser (Int -> Permissions -> Bool -> Bool -> Role)
-> Parser Int -> Parser (Permissions -> Bool -> Bool -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"position"
      Parser (Permissions -> Bool -> Bool -> Role)
-> Parser Permissions -> Parser (Bool -> Bool -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Permissions
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"permissions"
      Parser (Bool -> Bool -> Role)
-> Parser Bool -> Parser (Bool -> Role)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"managed"
      Parser (Bool -> Role) -> Parser Bool -> Parser Role
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"mentionable"

$(makeFieldLabelsNoPrefix ''Role)