-- | The generic guild channel type
module Calamity.Types.Model.Channel.Guild (
  GuildChannel (..),
  module Calamity.Types.Model.Channel.Guild.Category,
  module Calamity.Types.Model.Channel.Guild.Text,
  module Calamity.Types.Model.Channel.Guild.Voice,
) where

import Calamity.Internal.SnowflakeMap (SnowflakeMap)
import {-# SOURCE #-} Calamity.Types.Model.Channel
import Calamity.Types.Model.Channel.ChannelType
import Calamity.Types.Model.Channel.Guild.Category
import Calamity.Types.Model.Channel.Guild.Text
import Calamity.Types.Model.Channel.Guild.Voice
import {-# SOURCE #-} Calamity.Types.Model.Guild.Guild
import Calamity.Types.Model.Guild.Overwrite
import Calamity.Types.Snowflake
import Control.DeepSeq (NFData)
import Control.Lens
import Data.Aeson
import Data.Generics.Product.Fields
import Data.Text (Text)
import GHC.Generics
import TextShow
import qualified TextShow.Generic as TSG

data GuildChannel
  = GuildTextChannel TextChannel
  | GuildVoiceChannel VoiceChannel
  | GuildCategory Category
  deriving (Int -> GuildChannel -> ShowS
[GuildChannel] -> ShowS
GuildChannel -> String
(Int -> GuildChannel -> ShowS)
-> (GuildChannel -> String)
-> ([GuildChannel] -> ShowS)
-> Show GuildChannel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GuildChannel] -> ShowS
$cshowList :: [GuildChannel] -> ShowS
show :: GuildChannel -> String
$cshow :: GuildChannel -> String
showsPrec :: Int -> GuildChannel -> ShowS
$cshowsPrec :: Int -> GuildChannel -> ShowS
Show, GuildChannel -> GuildChannel -> Bool
(GuildChannel -> GuildChannel -> Bool)
-> (GuildChannel -> GuildChannel -> Bool) -> Eq GuildChannel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GuildChannel -> GuildChannel -> Bool
$c/= :: GuildChannel -> GuildChannel -> Bool
== :: GuildChannel -> GuildChannel -> Bool
$c== :: GuildChannel -> GuildChannel -> Bool
Eq, (forall x. GuildChannel -> Rep GuildChannel x)
-> (forall x. Rep GuildChannel x -> GuildChannel)
-> Generic GuildChannel
forall x. Rep GuildChannel x -> GuildChannel
forall x. GuildChannel -> Rep GuildChannel x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GuildChannel x -> GuildChannel
$cfrom :: forall x. GuildChannel -> Rep GuildChannel x
Generic, GuildChannel -> ()
(GuildChannel -> ()) -> NFData GuildChannel
forall a. (a -> ()) -> NFData a
rnf :: GuildChannel -> ()
$crnf :: GuildChannel -> ()
NFData)
  deriving (Int -> GuildChannel -> Builder
Int -> GuildChannel -> Text
Int -> GuildChannel -> Text
[GuildChannel] -> Builder
[GuildChannel] -> Text
[GuildChannel] -> Text
GuildChannel -> Builder
GuildChannel -> Text
GuildChannel -> Text
(Int -> GuildChannel -> Builder)
-> (GuildChannel -> Builder)
-> ([GuildChannel] -> Builder)
-> (Int -> GuildChannel -> Text)
-> (GuildChannel -> Text)
-> ([GuildChannel] -> Text)
-> (Int -> GuildChannel -> Text)
-> (GuildChannel -> Text)
-> ([GuildChannel] -> Text)
-> TextShow GuildChannel
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
showtlList :: [GuildChannel] -> Text
$cshowtlList :: [GuildChannel] -> Text
showtl :: GuildChannel -> Text
$cshowtl :: GuildChannel -> Text
showtlPrec :: Int -> GuildChannel -> Text
$cshowtlPrec :: Int -> GuildChannel -> Text
showtList :: [GuildChannel] -> Text
$cshowtList :: [GuildChannel] -> Text
showt :: GuildChannel -> Text
$cshowt :: GuildChannel -> Text
showtPrec :: Int -> GuildChannel -> Text
$cshowtPrec :: Int -> GuildChannel -> Text
showbList :: [GuildChannel] -> Builder
$cshowbList :: [GuildChannel] -> Builder
showb :: GuildChannel -> Builder
$cshowb :: GuildChannel -> Builder
showbPrec :: Int -> GuildChannel -> Builder
$cshowbPrec :: Int -> GuildChannel -> Builder
TextShow) via TSG.FromGeneric GuildChannel

instance FromJSON GuildChannel where
  parseJSON :: Value -> Parser GuildChannel
parseJSON = String
-> (Object -> Parser GuildChannel) -> Value -> Parser GuildChannel
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"GuildChannel" ((Object -> Parser GuildChannel) -> Value -> Parser GuildChannel)
-> (Object -> Parser GuildChannel) -> Value -> Parser GuildChannel
forall a b. (a -> b) -> a -> b
$ \Object
v -> do
    ChannelType
type_ <- Object
v Object -> Key -> Parser ChannelType
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type"

    case ChannelType
type_ of
      ChannelType
GuildTextType -> TextChannel -> GuildChannel
GuildTextChannel (TextChannel -> GuildChannel)
-> Parser TextChannel -> Parser GuildChannel
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser TextChannel
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
v)
      ChannelType
GuildVoiceType -> VoiceChannel -> GuildChannel
GuildVoiceChannel (VoiceChannel -> GuildChannel)
-> Parser VoiceChannel -> Parser GuildChannel
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser VoiceChannel
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
v)
      ChannelType
GuildCategoryType -> Category -> GuildChannel
GuildCategory (Category -> GuildChannel)
-> Parser Category -> Parser GuildChannel
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Category
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
v)
      ChannelType
typ -> String -> Parser GuildChannel
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser GuildChannel) -> String -> Parser GuildChannel
forall a b. (a -> b) -> a -> b
$ String
"Not a valid guild channel: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ChannelType -> String
forall a. Show a => a -> String
show ChannelType
typ

instance HasID GuildChannel GuildChannel where
  getID :: GuildChannel -> Snowflake GuildChannel
getID (GuildTextChannel TextChannel
a) = Snowflake TextChannel -> Snowflake GuildChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake TextChannel -> Snowflake GuildChannel)
-> Snowflake TextChannel -> Snowflake GuildChannel
forall a b. (a -> b) -> a -> b
$ TextChannel
a TextChannel
-> Getting
     (Snowflake TextChannel) TextChannel (Snowflake TextChannel)
-> Snowflake TextChannel
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' "id" s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @"id"
  getID (GuildVoiceChannel VoiceChannel
a) = Snowflake VoiceChannel -> Snowflake GuildChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake VoiceChannel -> Snowflake GuildChannel)
-> Snowflake VoiceChannel -> Snowflake GuildChannel
forall a b. (a -> b) -> a -> b
$ VoiceChannel
a VoiceChannel
-> Getting
     (Snowflake VoiceChannel) VoiceChannel (Snowflake VoiceChannel)
-> Snowflake VoiceChannel
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' "id" s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @"id"
  getID (GuildCategory Category
a) = Snowflake Category -> Snowflake GuildChannel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake Category -> Snowflake GuildChannel)
-> Snowflake Category -> Snowflake GuildChannel
forall a b. (a -> b) -> a -> b
$ Category
a Category
-> Getting (Snowflake Category) Category (Snowflake Category)
-> Snowflake Category
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' "id" s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @"id"

instance HasID Channel GuildChannel where
  getID :: GuildChannel -> Snowflake Channel
getID = Snowflake GuildChannel -> Snowflake Channel
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake GuildChannel -> Snowflake Channel)
-> (GuildChannel -> Snowflake GuildChannel)
-> GuildChannel
-> Snowflake Channel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasID GuildChannel a => a -> Snowflake GuildChannel
forall b a. HasID b a => a -> Snowflake b
getID @GuildChannel

instance HasID Guild GuildChannel where
  getID :: GuildChannel -> Snowflake Guild
getID (GuildTextChannel TextChannel
a) = Snowflake Guild -> Snowflake Guild
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake Guild -> Snowflake Guild)
-> Snowflake Guild -> Snowflake Guild
forall a b. (a -> b) -> a -> b
$ TextChannel
a TextChannel
-> Getting (Snowflake Guild) TextChannel (Snowflake Guild)
-> Snowflake Guild
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' "guildID" s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @"guildID"
  getID (GuildVoiceChannel VoiceChannel
a) = Snowflake Guild -> Snowflake Guild
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake Guild -> Snowflake Guild)
-> Snowflake Guild -> Snowflake Guild
forall a b. (a -> b) -> a -> b
$ VoiceChannel
a VoiceChannel
-> Getting (Snowflake Guild) VoiceChannel (Snowflake Guild)
-> Snowflake Guild
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' "guildID" s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @"guildID"
  getID (GuildCategory Category
a) = Snowflake Guild -> Snowflake Guild
forall a b. Snowflake a -> Snowflake b
coerceSnowflake (Snowflake Guild -> Snowflake Guild)
-> Snowflake Guild -> Snowflake Guild
forall a b. (a -> b) -> a -> b
$ Category
a Category
-> Getting (Snowflake Guild) Category (Snowflake Guild)
-> Snowflake Guild
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' "guildID" s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @"guildID"

instance {-# OVERLAPS #-} HasField' "name" GuildChannel Text where
  field' :: (Text -> f Text) -> GuildChannel -> f GuildChannel
field' = (GuildChannel -> Text)
-> (GuildChannel -> Text -> GuildChannel)
-> Lens GuildChannel GuildChannel Text Text
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens GuildChannel -> Text
get GuildChannel -> Text -> GuildChannel
set
   where
    get :: GuildChannel -> Text
get (GuildTextChannel (TextChannel{Text
$sel:name:TextChannel :: TextChannel -> Text
name :: Text
name})) = Text
name
    get (GuildVoiceChannel (VoiceChannel{Text
$sel:name:VoiceChannel :: VoiceChannel -> Text
name :: Text
name})) = Text
name
    get (GuildCategory (Category{Text
$sel:name:Category :: Category -> Text
name :: Text
name})) = Text
name

    set :: GuildChannel -> Text -> GuildChannel
set (GuildTextChannel TextChannel
t) Text
v = TextChannel -> GuildChannel
GuildTextChannel (TextChannel
t{$sel:name:TextChannel :: Text
name = Text
v})
    set (GuildVoiceChannel VoiceChannel
t) Text
v = VoiceChannel -> GuildChannel
GuildVoiceChannel (VoiceChannel
t{$sel:name:VoiceChannel :: Text
name = Text
v})
    set (GuildCategory Category
t) Text
v = Category -> GuildChannel
GuildCategory (Category
t{$sel:name:Category :: Text
name = Text
v})

instance {-# OVERLAPS #-} HasField' "permissionOverwrites" GuildChannel (SnowflakeMap Overwrite) where
  field' :: (SnowflakeMap Overwrite -> f (SnowflakeMap Overwrite))
-> GuildChannel -> f GuildChannel
field' = (GuildChannel -> SnowflakeMap Overwrite)
-> (GuildChannel -> SnowflakeMap Overwrite -> GuildChannel)
-> Lens
     GuildChannel
     GuildChannel
     (SnowflakeMap Overwrite)
     (SnowflakeMap Overwrite)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens GuildChannel -> SnowflakeMap Overwrite
get GuildChannel -> SnowflakeMap Overwrite -> GuildChannel
set
   where
    get :: GuildChannel -> SnowflakeMap Overwrite
get (GuildTextChannel (TextChannel{SnowflakeMap Overwrite
$sel:permissionOverwrites:TextChannel :: TextChannel -> SnowflakeMap Overwrite
permissionOverwrites :: SnowflakeMap Overwrite
permissionOverwrites})) = SnowflakeMap Overwrite
permissionOverwrites
    get (GuildVoiceChannel (VoiceChannel{SnowflakeMap Overwrite
$sel:permissionOverwrites:VoiceChannel :: VoiceChannel -> SnowflakeMap Overwrite
permissionOverwrites :: SnowflakeMap Overwrite
permissionOverwrites})) = SnowflakeMap Overwrite
permissionOverwrites
    get (GuildCategory (Category{SnowflakeMap Overwrite
$sel:permissionOverwrites:Category :: Category -> SnowflakeMap Overwrite
permissionOverwrites :: SnowflakeMap Overwrite
permissionOverwrites})) = SnowflakeMap Overwrite
permissionOverwrites

    set :: GuildChannel -> SnowflakeMap Overwrite -> GuildChannel
set (GuildTextChannel TextChannel
t) SnowflakeMap Overwrite
v = TextChannel -> GuildChannel
GuildTextChannel (TextChannel
t{$sel:permissionOverwrites:TextChannel :: SnowflakeMap Overwrite
permissionOverwrites = SnowflakeMap Overwrite
v})
    set (GuildVoiceChannel VoiceChannel
t) SnowflakeMap Overwrite
v = VoiceChannel -> GuildChannel
GuildVoiceChannel (VoiceChannel
t{$sel:permissionOverwrites:VoiceChannel :: SnowflakeMap Overwrite
permissionOverwrites = SnowflakeMap Overwrite
v})
    set (GuildCategory Category
t) SnowflakeMap Overwrite
v = Category -> GuildChannel
GuildCategory (Category
t{$sel:permissionOverwrites:Category :: SnowflakeMap Overwrite
permissionOverwrites = SnowflakeMap Overwrite
v})

instance {-# OVERLAPS #-} HasField' "position" GuildChannel Int where
  field' :: (Int -> f Int) -> GuildChannel -> f GuildChannel
field' = (GuildChannel -> Int)
-> (GuildChannel -> Int -> GuildChannel)
-> Lens GuildChannel GuildChannel Int Int
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens GuildChannel -> Int
get GuildChannel -> Int -> GuildChannel
set
   where
    get :: GuildChannel -> Int
get (GuildTextChannel (TextChannel{Int
$sel:position:TextChannel :: TextChannel -> Int
position :: Int
position})) = Int
position
    get (GuildVoiceChannel (VoiceChannel{Int
$sel:position:VoiceChannel :: VoiceChannel -> Int
position :: Int
position})) = Int
position
    get (GuildCategory (Category{Int
$sel:position:Category :: Category -> Int
position :: Int
position})) = Int
position

    set :: GuildChannel -> Int -> GuildChannel
set (GuildTextChannel TextChannel
t) Int
v = TextChannel -> GuildChannel
GuildTextChannel (TextChannel
t{$sel:position:TextChannel :: Int
position = Int
v})
    set (GuildVoiceChannel VoiceChannel
t) Int
v = VoiceChannel -> GuildChannel
GuildVoiceChannel (VoiceChannel
t{$sel:position:VoiceChannel :: Int
position = Int
v})
    set (GuildCategory Category
t) Int
v = Category -> GuildChannel
GuildCategory (Category
t{$sel:position:Category :: Int
position = Int
v})