{-# LANGUAGE TemplateHaskell #-}

-- | Types of channels
module Calamity.Types.Model.Channel.ChannelType (ChannelType (..)) where

import Data.Aeson qualified as Aeson
import Data.Scientific
import Optics.TH
import TextShow.TH

-- Thanks sbrg (https://github.com/saevarb/haskord/blob/d1bb07bcc4f3dbc29f2dfd3351ff9f16fc100c07/haskord-lib/src/Haskord/Types/Common.hsfield#L182)
data ChannelType
  = GuildTextType
  | DMType
  | GuildVoiceType
  | GroupDMType
  | GuildCategoryType
  | GuildNewsType
  | GuildNewsThreadType
  | GuildPublicThreadType
  | GuildPrivateThreadType
  | GuildStageVoiceType
  | GuildDirectoryType
  | GuildForumType
  deriving (ChannelType -> ChannelType -> Bool
(ChannelType -> ChannelType -> Bool)
-> (ChannelType -> ChannelType -> Bool) -> Eq ChannelType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChannelType -> ChannelType -> Bool
== :: ChannelType -> ChannelType -> Bool
$c/= :: ChannelType -> ChannelType -> Bool
/= :: ChannelType -> ChannelType -> Bool
Eq, Int -> ChannelType -> ShowS
[ChannelType] -> ShowS
ChannelType -> String
(Int -> ChannelType -> ShowS)
-> (ChannelType -> String)
-> ([ChannelType] -> ShowS)
-> Show ChannelType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChannelType -> ShowS
showsPrec :: Int -> ChannelType -> ShowS
$cshow :: ChannelType -> String
show :: ChannelType -> String
$cshowList :: [ChannelType] -> ShowS
showList :: [ChannelType] -> ShowS
Show, Int -> ChannelType
ChannelType -> Int
ChannelType -> [ChannelType]
ChannelType -> ChannelType
ChannelType -> ChannelType -> [ChannelType]
ChannelType -> ChannelType -> ChannelType -> [ChannelType]
(ChannelType -> ChannelType)
-> (ChannelType -> ChannelType)
-> (Int -> ChannelType)
-> (ChannelType -> Int)
-> (ChannelType -> [ChannelType])
-> (ChannelType -> ChannelType -> [ChannelType])
-> (ChannelType -> ChannelType -> [ChannelType])
-> (ChannelType -> ChannelType -> ChannelType -> [ChannelType])
-> Enum ChannelType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: ChannelType -> ChannelType
succ :: ChannelType -> ChannelType
$cpred :: ChannelType -> ChannelType
pred :: ChannelType -> ChannelType
$ctoEnum :: Int -> ChannelType
toEnum :: Int -> ChannelType
$cfromEnum :: ChannelType -> Int
fromEnum :: ChannelType -> Int
$cenumFrom :: ChannelType -> [ChannelType]
enumFrom :: ChannelType -> [ChannelType]
$cenumFromThen :: ChannelType -> ChannelType -> [ChannelType]
enumFromThen :: ChannelType -> ChannelType -> [ChannelType]
$cenumFromTo :: ChannelType -> ChannelType -> [ChannelType]
enumFromTo :: ChannelType -> ChannelType -> [ChannelType]
$cenumFromThenTo :: ChannelType -> ChannelType -> ChannelType -> [ChannelType]
enumFromThenTo :: ChannelType -> ChannelType -> ChannelType -> [ChannelType]
Enum)

$(deriveTextShow ''ChannelType)
$(makeFieldLabelsNoPrefix ''ChannelType)

instance Aeson.ToJSON ChannelType where
  toJSON :: ChannelType -> Value
toJSON ChannelType
t = Int -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (ChannelType -> Int
forall a. Enum a => a -> Int
fromEnum ChannelType
t)
  toEncoding :: ChannelType -> Encoding
toEncoding ChannelType
t = Int -> Encoding
forall a. ToJSON a => a -> Encoding
Aeson.toEncoding (ChannelType -> Int
forall a. Enum a => a -> Int
fromEnum ChannelType
t)

instance Aeson.FromJSON ChannelType where
  parseJSON :: Value -> Parser ChannelType
parseJSON = String
-> (Scientific -> Parser ChannelType)
-> Value
-> Parser ChannelType
forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
Aeson.withScientific String
"ChannelType" ((Scientific -> Parser ChannelType) -> Value -> Parser ChannelType)
-> (Scientific -> Parser ChannelType)
-> Value
-> Parser ChannelType
forall a b. (a -> b) -> a -> b
$ \Scientific
n -> case forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger @Int Scientific
n of
    Just Int
v -> case Int
v of
      Int
0 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildTextType
      Int
1 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
DMType
      Int
2 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildVoiceType
      Int
3 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GroupDMType
      Int
4 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildCategoryType
      Int
5 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildNewsType
      Int
10 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildNewsThreadType
      Int
11 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildPublicThreadType
      Int
12 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildPrivateThreadType
      Int
13 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildStageVoiceType
      Int
14 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildDirectoryType
      Int
15 -> ChannelType -> Parser ChannelType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ChannelType
GuildForumType
      Int
_ -> String -> Parser ChannelType
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ChannelType) -> String -> Parser ChannelType
forall a b. (a -> b) -> a -> b
$ String
"Invalid ChannelType: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Scientific -> String
forall a. Show a => a -> String
show Scientific
n
    Maybe Int
Nothing -> String -> Parser ChannelType
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ChannelType) -> String -> Parser ChannelType
forall a b. (a -> b) -> a -> b
$ String
"Invalid ChannelType: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Scientific -> String
forall a. Show a => a -> String
show Scientific
n