{-# LANGUAGE OverloadedStrings #-}

-- | Data structures pertaining to gateway dispatch 'Event's
module Discord.Internal.Types.Events where

import Prelude hiding (id)

import Data.Time.ISO8601 (parseISO8601)
import Data.Time (UTCTime)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)

import Data.Aeson
import Data.Aeson.Types
import qualified Data.Text as T

import Discord.Internal.Types.Prelude
import Discord.Internal.Types.Channel
import Discord.Internal.Types.Guild
import Discord.Internal.Types.User (User)


-- | Represents possible events sent by discord. Detailed information can be found at https://discord.com/developers/docs/topics/gateway.
data Event =
    Ready                   Int User [Channel] [GuildUnavailable] T.Text
  | Resumed                 [T.Text]
  | ChannelCreate           Channel
  | ChannelUpdate           Channel
  | ChannelDelete           Channel
  | ChannelPinsUpdate       ChannelId (Maybe UTCTime)
  | GuildCreate             Guild GuildInfo
  | GuildUpdate             Guild
  | GuildDelete             GuildUnavailable
  | GuildBanAdd             GuildId User
  | GuildBanRemove          GuildId User
  | GuildEmojiUpdate        GuildId [Emoji]
  | GuildIntegrationsUpdate GuildId
  | GuildMemberAdd          GuildId GuildMember
  | GuildMemberRemove       GuildId User
  | GuildMemberUpdate       GuildId [RoleId] User (Maybe T.Text)
  | GuildMemberChunk        GuildId [GuildMember]
  | GuildRoleCreate         GuildId Role
  | GuildRoleUpdate         GuildId Role
  | GuildRoleDelete         GuildId RoleId
  | MessageCreate           Message
  | MessageUpdate           ChannelId MessageId
  | MessageDelete           ChannelId MessageId
  | MessageDeleteBulk       ChannelId [MessageId]
  | MessageReactionAdd      ReactionInfo
  | MessageReactionRemove   ReactionInfo
  | MessageReactionRemoveAll ChannelId MessageId
  | MessageReactionRemoveEmoji ReactionRemoveInfo
  | PresenceUpdate          PresenceInfo
  | TypingStart             TypingInfo
  | UserUpdate              User
  -- | VoiceStateUpdate
  -- | VoiceServerUpdate
  | UnknownEvent     T.Text Object
  deriving (Int -> Event -> ShowS
[Event] -> ShowS
Event -> String
(Int -> Event -> ShowS)
-> (Event -> String) -> ([Event] -> ShowS) -> Show Event
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Event] -> ShowS
$cshowList :: [Event] -> ShowS
show :: Event -> String
$cshow :: Event -> String
showsPrec :: Int -> Event -> ShowS
$cshowsPrec :: Int -> Event -> ShowS
Show, Event -> Event -> Bool
(Event -> Event -> Bool) -> (Event -> Event -> Bool) -> Eq Event
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Event -> Event -> Bool
$c/= :: Event -> Event -> Bool
== :: Event -> Event -> Bool
$c== :: Event -> Event -> Bool
Eq)

data ReactionInfo = ReactionInfo
  { ReactionInfo -> UserId
reactionUserId    :: UserId
  , ReactionInfo -> Maybe UserId
reactionGuildId   :: Maybe GuildId
  , ReactionInfo -> UserId
reactionChannelId :: ChannelId
  , ReactionInfo -> UserId
reactionMessageId :: MessageId
  , ReactionInfo -> Emoji
reactionEmoji     :: Emoji
  } deriving (Int -> ReactionInfo -> ShowS
[ReactionInfo] -> ShowS
ReactionInfo -> String
(Int -> ReactionInfo -> ShowS)
-> (ReactionInfo -> String)
-> ([ReactionInfo] -> ShowS)
-> Show ReactionInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReactionInfo] -> ShowS
$cshowList :: [ReactionInfo] -> ShowS
show :: ReactionInfo -> String
$cshow :: ReactionInfo -> String
showsPrec :: Int -> ReactionInfo -> ShowS
$cshowsPrec :: Int -> ReactionInfo -> ShowS
Show, ReactionInfo -> ReactionInfo -> Bool
(ReactionInfo -> ReactionInfo -> Bool)
-> (ReactionInfo -> ReactionInfo -> Bool) -> Eq ReactionInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReactionInfo -> ReactionInfo -> Bool
$c/= :: ReactionInfo -> ReactionInfo -> Bool
== :: ReactionInfo -> ReactionInfo -> Bool
$c== :: ReactionInfo -> ReactionInfo -> Bool
Eq, Eq ReactionInfo
Eq ReactionInfo
-> (ReactionInfo -> ReactionInfo -> Ordering)
-> (ReactionInfo -> ReactionInfo -> Bool)
-> (ReactionInfo -> ReactionInfo -> Bool)
-> (ReactionInfo -> ReactionInfo -> Bool)
-> (ReactionInfo -> ReactionInfo -> Bool)
-> (ReactionInfo -> ReactionInfo -> ReactionInfo)
-> (ReactionInfo -> ReactionInfo -> ReactionInfo)
-> Ord ReactionInfo
ReactionInfo -> ReactionInfo -> Bool
ReactionInfo -> ReactionInfo -> Ordering
ReactionInfo -> ReactionInfo -> ReactionInfo
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 :: ReactionInfo -> ReactionInfo -> ReactionInfo
$cmin :: ReactionInfo -> ReactionInfo -> ReactionInfo
max :: ReactionInfo -> ReactionInfo -> ReactionInfo
$cmax :: ReactionInfo -> ReactionInfo -> ReactionInfo
>= :: ReactionInfo -> ReactionInfo -> Bool
$c>= :: ReactionInfo -> ReactionInfo -> Bool
> :: ReactionInfo -> ReactionInfo -> Bool
$c> :: ReactionInfo -> ReactionInfo -> Bool
<= :: ReactionInfo -> ReactionInfo -> Bool
$c<= :: ReactionInfo -> ReactionInfo -> Bool
< :: ReactionInfo -> ReactionInfo -> Bool
$c< :: ReactionInfo -> ReactionInfo -> Bool
compare :: ReactionInfo -> ReactionInfo -> Ordering
$ccompare :: ReactionInfo -> ReactionInfo -> Ordering
$cp1Ord :: Eq ReactionInfo
Ord)

instance FromJSON ReactionInfo where
  parseJSON :: Value -> Parser ReactionInfo
parseJSON = String
-> (Object -> Parser ReactionInfo) -> Value -> Parser ReactionInfo
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"ReactionInfo" ((Object -> Parser ReactionInfo) -> Value -> Parser ReactionInfo)
-> (Object -> Parser ReactionInfo) -> Value -> Parser ReactionInfo
forall a b. (a -> b) -> a -> b
$ \Object
o ->
    UserId -> Maybe UserId -> UserId -> UserId -> Emoji -> ReactionInfo
ReactionInfo (UserId
 -> Maybe UserId -> UserId -> UserId -> Emoji -> ReactionInfo)
-> Parser UserId
-> Parser
     (Maybe UserId -> UserId -> UserId -> Emoji -> ReactionInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"user_id"
                 Parser (Maybe UserId -> UserId -> UserId -> Emoji -> ReactionInfo)
-> Parser (Maybe UserId)
-> Parser (UserId -> UserId -> Emoji -> ReactionInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser (Maybe UserId)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"guild_id"
                 Parser (UserId -> UserId -> Emoji -> ReactionInfo)
-> Parser UserId -> Parser (UserId -> Emoji -> ReactionInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"channel_id"
                 Parser (UserId -> Emoji -> ReactionInfo)
-> Parser UserId -> Parser (Emoji -> ReactionInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"message_id"
                 Parser (Emoji -> ReactionInfo)
-> Parser Emoji -> Parser ReactionInfo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Emoji
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"emoji"

data ReactionRemoveInfo  = ReactionRemoveInfo
  { ReactionRemoveInfo -> UserId
reactionRemoveChannelId :: ChannelId
  , ReactionRemoveInfo -> UserId
reactionRemoveGuildId   :: GuildId
  , ReactionRemoveInfo -> UserId
reactionRemoveMessageId :: MessageId
  , ReactionRemoveInfo -> Emoji
reactionRemoveEmoji     :: Emoji
  } deriving (Int -> ReactionRemoveInfo -> ShowS
[ReactionRemoveInfo] -> ShowS
ReactionRemoveInfo -> String
(Int -> ReactionRemoveInfo -> ShowS)
-> (ReactionRemoveInfo -> String)
-> ([ReactionRemoveInfo] -> ShowS)
-> Show ReactionRemoveInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReactionRemoveInfo] -> ShowS
$cshowList :: [ReactionRemoveInfo] -> ShowS
show :: ReactionRemoveInfo -> String
$cshow :: ReactionRemoveInfo -> String
showsPrec :: Int -> ReactionRemoveInfo -> ShowS
$cshowsPrec :: Int -> ReactionRemoveInfo -> ShowS
Show, ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
(ReactionRemoveInfo -> ReactionRemoveInfo -> Bool)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> Bool)
-> Eq ReactionRemoveInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
$c/= :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
== :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
$c== :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
Eq, Eq ReactionRemoveInfo
Eq ReactionRemoveInfo
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> Ordering)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> Bool)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> Bool)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> Bool)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> Bool)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo)
-> (ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo)
-> Ord ReactionRemoveInfo
ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
ReactionRemoveInfo -> ReactionRemoveInfo -> Ordering
ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo
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 :: ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo
$cmin :: ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo
max :: ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo
$cmax :: ReactionRemoveInfo -> ReactionRemoveInfo -> ReactionRemoveInfo
>= :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
$c>= :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
> :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
$c> :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
<= :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
$c<= :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
< :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
$c< :: ReactionRemoveInfo -> ReactionRemoveInfo -> Bool
compare :: ReactionRemoveInfo -> ReactionRemoveInfo -> Ordering
$ccompare :: ReactionRemoveInfo -> ReactionRemoveInfo -> Ordering
$cp1Ord :: Eq ReactionRemoveInfo
Ord)

instance FromJSON ReactionRemoveInfo where
  parseJSON :: Value -> Parser ReactionRemoveInfo
parseJSON = String
-> (Object -> Parser ReactionRemoveInfo)
-> Value
-> Parser ReactionRemoveInfo
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"ReactionRemoveInfo" ((Object -> Parser ReactionRemoveInfo)
 -> Value -> Parser ReactionRemoveInfo)
-> (Object -> Parser ReactionRemoveInfo)
-> Value
-> Parser ReactionRemoveInfo
forall a b. (a -> b) -> a -> b
$ \Object
o ->
    UserId -> UserId -> UserId -> Emoji -> ReactionRemoveInfo
ReactionRemoveInfo (UserId -> UserId -> UserId -> Emoji -> ReactionRemoveInfo)
-> Parser UserId
-> Parser (UserId -> UserId -> Emoji -> ReactionRemoveInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"guild_id"
                       Parser (UserId -> UserId -> Emoji -> ReactionRemoveInfo)
-> Parser UserId -> Parser (UserId -> Emoji -> ReactionRemoveInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"channel_id"
                       Parser (UserId -> Emoji -> ReactionRemoveInfo)
-> Parser UserId -> Parser (Emoji -> ReactionRemoveInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"message_id"
                       Parser (Emoji -> ReactionRemoveInfo)
-> Parser Emoji -> Parser ReactionRemoveInfo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Emoji
forall a. FromJSON a => Object -> Text -> Parser a
.:  Text
"emoji"

data PresenceInfo = PresenceInfo
  { PresenceInfo -> UserId
presenceUserId  :: UserId
  , PresenceInfo -> [UserId]
presenceRoles   :: [RoleId]
  -- , presenceGame :: Maybe Activity
  , PresenceInfo -> UserId
presenceGuildId :: GuildId
  , PresenceInfo -> Text
presenceStatus  :: T.Text
  } deriving (Int -> PresenceInfo -> ShowS
[PresenceInfo] -> ShowS
PresenceInfo -> String
(Int -> PresenceInfo -> ShowS)
-> (PresenceInfo -> String)
-> ([PresenceInfo] -> ShowS)
-> Show PresenceInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PresenceInfo] -> ShowS
$cshowList :: [PresenceInfo] -> ShowS
show :: PresenceInfo -> String
$cshow :: PresenceInfo -> String
showsPrec :: Int -> PresenceInfo -> ShowS
$cshowsPrec :: Int -> PresenceInfo -> ShowS
Show, PresenceInfo -> PresenceInfo -> Bool
(PresenceInfo -> PresenceInfo -> Bool)
-> (PresenceInfo -> PresenceInfo -> Bool) -> Eq PresenceInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PresenceInfo -> PresenceInfo -> Bool
$c/= :: PresenceInfo -> PresenceInfo -> Bool
== :: PresenceInfo -> PresenceInfo -> Bool
$c== :: PresenceInfo -> PresenceInfo -> Bool
Eq, Eq PresenceInfo
Eq PresenceInfo
-> (PresenceInfo -> PresenceInfo -> Ordering)
-> (PresenceInfo -> PresenceInfo -> Bool)
-> (PresenceInfo -> PresenceInfo -> Bool)
-> (PresenceInfo -> PresenceInfo -> Bool)
-> (PresenceInfo -> PresenceInfo -> Bool)
-> (PresenceInfo -> PresenceInfo -> PresenceInfo)
-> (PresenceInfo -> PresenceInfo -> PresenceInfo)
-> Ord PresenceInfo
PresenceInfo -> PresenceInfo -> Bool
PresenceInfo -> PresenceInfo -> Ordering
PresenceInfo -> PresenceInfo -> PresenceInfo
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 :: PresenceInfo -> PresenceInfo -> PresenceInfo
$cmin :: PresenceInfo -> PresenceInfo -> PresenceInfo
max :: PresenceInfo -> PresenceInfo -> PresenceInfo
$cmax :: PresenceInfo -> PresenceInfo -> PresenceInfo
>= :: PresenceInfo -> PresenceInfo -> Bool
$c>= :: PresenceInfo -> PresenceInfo -> Bool
> :: PresenceInfo -> PresenceInfo -> Bool
$c> :: PresenceInfo -> PresenceInfo -> Bool
<= :: PresenceInfo -> PresenceInfo -> Bool
$c<= :: PresenceInfo -> PresenceInfo -> Bool
< :: PresenceInfo -> PresenceInfo -> Bool
$c< :: PresenceInfo -> PresenceInfo -> Bool
compare :: PresenceInfo -> PresenceInfo -> Ordering
$ccompare :: PresenceInfo -> PresenceInfo -> Ordering
$cp1Ord :: Eq PresenceInfo
Ord)

instance FromJSON PresenceInfo where
  parseJSON :: Value -> Parser PresenceInfo
parseJSON = String
-> (Object -> Parser PresenceInfo) -> Value -> Parser PresenceInfo
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PresenceInfo" ((Object -> Parser PresenceInfo) -> Value -> Parser PresenceInfo)
-> (Object -> Parser PresenceInfo) -> Value -> Parser PresenceInfo
forall a b. (a -> b) -> a -> b
$ \Object
o ->
    UserId -> [UserId] -> UserId -> Text -> PresenceInfo
PresenceInfo (UserId -> [UserId] -> UserId -> Text -> PresenceInfo)
-> Parser UserId
-> Parser ([UserId] -> UserId -> Text -> PresenceInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
o Object -> Text -> Parser Object
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user" Parser Object -> (Object -> Parser UserId) -> Parser UserId
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"id"))
                 Parser ([UserId] -> UserId -> Text -> PresenceInfo)
-> Parser [UserId] -> Parser (UserId -> Text -> PresenceInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [UserId]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"roles"
              -- <*> o .: "game"
                 Parser (UserId -> Text -> PresenceInfo)
-> Parser UserId -> Parser (Text -> PresenceInfo)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id"
                 Parser (Text -> PresenceInfo) -> Parser Text -> Parser PresenceInfo
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"status"

data TypingInfo = TypingInfo
  { TypingInfo -> UserId
typingUserId    :: UserId
  , TypingInfo -> UserId
typingChannelId :: ChannelId
  , TypingInfo -> UTCTime
typingTimestamp :: UTCTime
  } deriving (Int -> TypingInfo -> ShowS
[TypingInfo] -> ShowS
TypingInfo -> String
(Int -> TypingInfo -> ShowS)
-> (TypingInfo -> String)
-> ([TypingInfo] -> ShowS)
-> Show TypingInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TypingInfo] -> ShowS
$cshowList :: [TypingInfo] -> ShowS
show :: TypingInfo -> String
$cshow :: TypingInfo -> String
showsPrec :: Int -> TypingInfo -> ShowS
$cshowsPrec :: Int -> TypingInfo -> ShowS
Show, TypingInfo -> TypingInfo -> Bool
(TypingInfo -> TypingInfo -> Bool)
-> (TypingInfo -> TypingInfo -> Bool) -> Eq TypingInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TypingInfo -> TypingInfo -> Bool
$c/= :: TypingInfo -> TypingInfo -> Bool
== :: TypingInfo -> TypingInfo -> Bool
$c== :: TypingInfo -> TypingInfo -> Bool
Eq, Eq TypingInfo
Eq TypingInfo
-> (TypingInfo -> TypingInfo -> Ordering)
-> (TypingInfo -> TypingInfo -> Bool)
-> (TypingInfo -> TypingInfo -> Bool)
-> (TypingInfo -> TypingInfo -> Bool)
-> (TypingInfo -> TypingInfo -> Bool)
-> (TypingInfo -> TypingInfo -> TypingInfo)
-> (TypingInfo -> TypingInfo -> TypingInfo)
-> Ord TypingInfo
TypingInfo -> TypingInfo -> Bool
TypingInfo -> TypingInfo -> Ordering
TypingInfo -> TypingInfo -> TypingInfo
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 :: TypingInfo -> TypingInfo -> TypingInfo
$cmin :: TypingInfo -> TypingInfo -> TypingInfo
max :: TypingInfo -> TypingInfo -> TypingInfo
$cmax :: TypingInfo -> TypingInfo -> TypingInfo
>= :: TypingInfo -> TypingInfo -> Bool
$c>= :: TypingInfo -> TypingInfo -> Bool
> :: TypingInfo -> TypingInfo -> Bool
$c> :: TypingInfo -> TypingInfo -> Bool
<= :: TypingInfo -> TypingInfo -> Bool
$c<= :: TypingInfo -> TypingInfo -> Bool
< :: TypingInfo -> TypingInfo -> Bool
$c< :: TypingInfo -> TypingInfo -> Bool
compare :: TypingInfo -> TypingInfo -> Ordering
$ccompare :: TypingInfo -> TypingInfo -> Ordering
$cp1Ord :: Eq TypingInfo
Ord)

instance FromJSON TypingInfo where
  parseJSON :: Value -> Parser TypingInfo
parseJSON = String
-> (Object -> Parser TypingInfo) -> Value -> Parser TypingInfo
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"TypingInfo" ((Object -> Parser TypingInfo) -> Value -> Parser TypingInfo)
-> (Object -> Parser TypingInfo) -> Value -> Parser TypingInfo
forall a b. (a -> b) -> a -> b
$ \Object
o ->
    do UserId
cid <- Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"channel_id"
       UserId
uid <- Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user_id"
       POSIXTime
posix <- Object
o Object -> Text -> Parser POSIXTime
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"timestamp"
       let utc :: UTCTime
utc = POSIXTime -> UTCTime
posixSecondsToUTCTime POSIXTime
posix
       TypingInfo -> Parser TypingInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure (UserId -> UserId -> UTCTime -> TypingInfo
TypingInfo UserId
uid UserId
cid UTCTime
utc)



-- | Convert ToJSON value to FromJSON value
reparse :: (ToJSON a, FromJSON b) => a -> Parser b
reparse :: a -> Parser b
reparse a
val = case (Value -> Parser b) -> Value -> Either String b
forall a b. (a -> Parser b) -> a -> Either String b
parseEither Value -> Parser b
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Either String b) -> Value -> Either String b
forall a b. (a -> b) -> a -> b
$ a -> Value
forall a. ToJSON a => a -> Value
toJSON a
val of
                Left String
r -> String -> Parser b
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
r
                Right b
b -> b -> Parser b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
b

eventParse :: T.Text -> Object -> Parser Event
eventParse :: Text -> Object -> Parser Event
eventParse Text
t Object
o = case Text
t of
    Text
"READY"                     -> Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Event
Ready (Int -> User -> [Channel] -> [GuildUnavailable] -> Text -> Event)
-> Parser Int
-> Parser
     (User -> [Channel] -> [GuildUnavailable] -> Text -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"v"
                                         Parser (User -> [Channel] -> [GuildUnavailable] -> Text -> Event)
-> Parser User
-> Parser ([Channel] -> [GuildUnavailable] -> Text -> Event)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser User
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user"
                                         Parser ([Channel] -> [GuildUnavailable] -> Text -> Event)
-> Parser [Channel] -> Parser ([GuildUnavailable] -> Text -> Event)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [Channel]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"private_channels"
                                         Parser ([GuildUnavailable] -> Text -> Event)
-> Parser [GuildUnavailable] -> Parser (Text -> Event)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [GuildUnavailable]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guilds"
                                         Parser (Text -> Event) -> Parser Text -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"session_id"
    Text
"RESUMED"                   -> [Text] -> Event
Resumed ([Text] -> Event) -> Parser [Text] -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser [Text]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"_trace"
    Text
"CHANNEL_CREATE"            -> Channel -> Event
ChannelCreate             (Channel -> Event) -> Parser Channel -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Channel
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"CHANNEL_UPDATE"            -> Channel -> Event
ChannelUpdate             (Channel -> Event) -> Parser Channel -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Channel
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"CHANNEL_DELETE"            -> Channel -> Event
ChannelDelete             (Channel -> Event) -> Parser Channel -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Channel
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"CHANNEL_PINS_UPDATE"       -> do UserId
id <- Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"channel_id"
                                      Maybe String
stamp <- Object
o Object -> Text -> Parser (Maybe String)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"last_pin_timestamp"
                                      let utc :: Maybe UTCTime
utc = Maybe String
stamp Maybe String -> (String -> Maybe UTCTime) -> Maybe UTCTime
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe UTCTime
parseISO8601
                                      Event -> Parser Event
forall (f :: * -> *) a. Applicative f => a -> f a
pure (UserId -> Maybe UTCTime -> Event
ChannelPinsUpdate UserId
id Maybe UTCTime
utc)
    Text
"GUILD_CREATE"              -> Guild -> GuildInfo -> Event
GuildCreate               (Guild -> GuildInfo -> Event)
-> Parser Guild -> Parser (GuildInfo -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Guild
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o Parser (GuildInfo -> Event) -> Parser GuildInfo -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object -> Parser GuildInfo
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"GUILD_UPDATE"              -> Guild -> Event
GuildUpdate               (Guild -> Event) -> Parser Guild -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Guild
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"GUILD_DELETE"              -> GuildUnavailable -> Event
GuildDelete               (GuildUnavailable -> Event)
-> Parser GuildUnavailable -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser GuildUnavailable
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"GUILD_BAN_ADD"             -> UserId -> User -> Event
GuildBanAdd    (UserId -> User -> Event)
-> Parser UserId -> Parser (User -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (User -> Event) -> Parser User -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser User
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user"
    Text
"GUILD_BAN_REMOVE"          -> UserId -> User -> Event
GuildBanRemove (UserId -> User -> Event)
-> Parser UserId -> Parser (User -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (User -> Event) -> Parser User -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser User
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user"
    Text
"GUILD_EMOJI_UPDATE"        -> UserId -> [Emoji] -> Event
GuildEmojiUpdate (UserId -> [Emoji] -> Event)
-> Parser UserId -> Parser ([Emoji] -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser ([Emoji] -> Event) -> Parser [Emoji] -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [Emoji]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"emojis"
    Text
"GUILD_INTEGRATIONS_UPDATE" -> UserId -> Event
GuildIntegrationsUpdate   (UserId -> Event) -> Parser UserId -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id"
    Text
"GUILD_MEMBER_ADD"          -> UserId -> GuildMember -> Event
GuildMemberAdd (UserId -> GuildMember -> Event)
-> Parser UserId -> Parser (GuildMember -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (GuildMember -> Event) -> Parser GuildMember -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object -> Parser GuildMember
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"GUILD_MEMBER_REMOVE"       -> UserId -> User -> Event
GuildMemberRemove (UserId -> User -> Event)
-> Parser UserId -> Parser (User -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (User -> Event) -> Parser User -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser User
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user"
    Text
"GUILD_MEMBER_UPDATE"       -> UserId -> [UserId] -> User -> Maybe Text -> Event
GuildMemberUpdate (UserId -> [UserId] -> User -> Maybe Text -> Event)
-> Parser UserId
-> Parser ([UserId] -> User -> Maybe Text -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id"
                                                     Parser ([UserId] -> User -> Maybe Text -> Event)
-> Parser [UserId] -> Parser (User -> Maybe Text -> Event)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [UserId]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"roles"
                                                     Parser (User -> Maybe Text -> Event)
-> Parser User -> Parser (Maybe Text -> Event)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser User
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"user"
                                                     Parser (Maybe Text -> Event) -> Parser (Maybe Text) -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"nick"
    Text
"GUILD_MEMBERS_CHUNK"       -> UserId -> [GuildMember] -> Event
GuildMemberChunk (UserId -> [GuildMember] -> Event)
-> Parser UserId -> Parser ([GuildMember] -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser ([GuildMember] -> Event)
-> Parser [GuildMember] -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [GuildMember]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"members"
    Text
"GUILD_ROLE_CREATE"         -> UserId -> Role -> Event
GuildRoleCreate  (UserId -> Role -> Event)
-> Parser UserId -> Parser (Role -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (Role -> Event) -> Parser Role -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Role
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"role"
    Text
"GUILD_ROLE_UPDATE"         -> UserId -> Role -> Event
GuildRoleUpdate  (UserId -> Role -> Event)
-> Parser UserId -> Parser (Role -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (Role -> Event) -> Parser Role -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Role
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"role"
    Text
"GUILD_ROLE_DELETE"         -> UserId -> UserId -> Event
GuildRoleDelete  (UserId -> UserId -> Event)
-> Parser UserId -> Parser (UserId -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"guild_id" Parser (UserId -> Event) -> Parser UserId -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"role_id"
    Text
"MESSAGE_CREATE"            -> Message -> Event
MessageCreate     (Message -> Event) -> Parser Message -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Message
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"MESSAGE_UPDATE"            -> UserId -> UserId -> Event
MessageUpdate     (UserId -> UserId -> Event)
-> Parser UserId -> Parser (UserId -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"channel_id" Parser (UserId -> Event) -> Parser UserId -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"id"
    Text
"MESSAGE_DELETE"            -> UserId -> UserId -> Event
MessageDelete     (UserId -> UserId -> Event)
-> Parser UserId -> Parser (UserId -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"channel_id" Parser (UserId -> Event) -> Parser UserId -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"id"
    Text
"MESSAGE_DELETE_BULK"       -> UserId -> [UserId] -> Event
MessageDeleteBulk (UserId -> [UserId] -> Event)
-> Parser UserId -> Parser ([UserId] -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"channel_id" Parser ([UserId] -> Event) -> Parser [UserId] -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser [UserId]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"ids"
    Text
"MESSAGE_REACTION_ADD"      -> ReactionInfo -> Event
MessageReactionAdd (ReactionInfo -> Event) -> Parser ReactionInfo -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser ReactionInfo
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"MESSAGE_REACTION_REMOVE"   -> ReactionInfo -> Event
MessageReactionRemove (ReactionInfo -> Event) -> Parser ReactionInfo -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser ReactionInfo
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"MESSAGE_REACTION_REMOVE_ALL" -> UserId -> UserId -> Event
MessageReactionRemoveAll (UserId -> UserId -> Event)
-> Parser UserId -> Parser (UserId -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"channel_id"
                                                              Parser (UserId -> Event) -> Parser UserId -> Parser Event
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser UserId
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"message_id"
    Text
"MESSAGE_REACTION_REMOVE_EMOJI" -> ReactionRemoveInfo -> Event
MessageReactionRemoveEmoji (ReactionRemoveInfo -> Event)
-> Parser ReactionRemoveInfo -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser ReactionRemoveInfo
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"PRESENCE_UPDATE"           -> PresenceInfo -> Event
PresenceUpdate            (PresenceInfo -> Event) -> Parser PresenceInfo -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser PresenceInfo
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"TYPING_START"              -> TypingInfo -> Event
TypingStart               (TypingInfo -> Event) -> Parser TypingInfo -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser TypingInfo
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
    Text
"USER_UPDATE"               -> User -> Event
UserUpdate                (User -> Event) -> Parser User -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser User
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o
 -- "VOICE_STATE_UPDATE"        -> VoiceStateUpdate          <$> reparse o
 -- "VOICE_SERVER_UPDATE"       -> VoiceServerUpdate         <$> reparse o
    Text
_other_event                -> Text -> Object -> Event
UnknownEvent Text
t            (Object -> Event) -> Parser Object -> Parser Event
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object -> Parser Object
forall a b. (ToJSON a, FromJSON b) => a -> Parser b
reparse Object
o