pusher-http-haskell-2.0.0.0: src/Network/Pusher/Protocol.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- |
-- Module : Network.Pusher.Protocol
-- Description : Types representing Pusher messages
-- Copyright : (c) Will Sewell, 2016
-- Licence : MIT
-- Maintainer : me@willsewell.com
-- Stability : stable
--
-- Types representing the JSON format of Pusher messages.
--
-- There are also types for query string parameters.
module Network.Pusher.Protocol
( ChannelInfo (..),
ChannelInfoAttributes (..),
ChannelInfoQuery (..),
ChannelsInfo (..),
ChannelsInfoQuery (..),
ChannelsInfoAttributes (..),
FullChannelInfo (..),
User (..),
Users (..),
ToURLParam,
toURLParam,
)
where
import Data.Aeson ((.:), (.:?))
import qualified Data.Aeson as A
import qualified Data.HashMap.Strict as HM
import qualified Data.HashSet as HS
import Data.Hashable (Hashable)
import qualified Data.Text as T
import GHC.Generics (Generic)
-- | Types that can be serialised to a querystring parameter value.
class ToURLParam a where
toURLParam :: a -> T.Text
-- | Enumeration of the attributes that can be queried about multiple channels.
data ChannelsInfoAttributes
= ChannelsUserCount
deriving (Eq, Generic)
instance ToURLParam ChannelsInfoAttributes where
toURLParam ChannelsUserCount = "user_count"
instance Hashable ChannelsInfoAttributes
-- | A set of requested 'ChannelsInfoAttributes'.
newtype ChannelsInfoQuery
= ChannelsInfoQuery (HS.HashSet ChannelsInfoAttributes)
deriving (ToURLParam)
-- | Enumeration of the attributes that can be queried about a single channel.
data ChannelInfoAttributes
= ChannelUserCount
| ChannelSubscriptionCount
deriving (Eq, Generic)
instance ToURLParam ChannelInfoAttributes where
toURLParam ChannelUserCount = "user_count"
toURLParam ChannelSubscriptionCount = "subscription_count"
instance Hashable ChannelInfoAttributes
-- | A set of requested 'ChannelInfoAttributes'.
newtype ChannelInfoQuery
= ChannelInfoQuery (HS.HashSet ChannelInfoAttributes)
deriving (ToURLParam)
instance ToURLParam a => ToURLParam (HS.HashSet a) where
toURLParam hs = T.intercalate "," $ toURLParam <$> HS.toList hs
-- | A map of channels to their 'ChannelInfo'. The result of querying channel
-- info from multiple channels.
newtype ChannelsInfo
= ChannelsInfo (HM.HashMap T.Text ChannelInfo)
deriving (Eq, Show)
instance A.FromJSON ChannelsInfo where
parseJSON =
A.withObject "ChannelsInfo" $ \v -> do
channelsV <- v .: "channels"
A.withObject
"HashMap"
(fmap ChannelsInfo . mapM A.parseJSON)
channelsV
-- | The possible returned channel attributes when multiple when multiple
-- channels are queried.
newtype ChannelInfo
= ChannelInfo
{ channelInfoUserCount :: Maybe Int
}
deriving (Eq, Show)
instance A.FromJSON ChannelInfo where
parseJSON =
A.withObject "ChannelInfo" $ \v -> ChannelInfo <$> v .:? "user_count"
-- | The possible values returned by a query to a single channel.
data FullChannelInfo
= FullChannelInfo
{ fullChannelInfoOccupied :: Bool,
fullChannelInfoUserCount :: Maybe Int,
fullChannelInfoSubCount :: Maybe Int
}
deriving (Eq, Show)
instance A.FromJSON FullChannelInfo where
parseJSON =
A.withObject "FullChannelInfo" $ \v ->
FullChannelInfo <$> v .: "occupied" <*> v .:? "user_count"
<*> v .:? "subscription_count"
-- | A list of users returned by querying for users in a presence channel.
newtype Users
= Users [User]
deriving (Eq, Show)
instance A.FromJSON Users where
parseJSON =
A.withObject "FullChannelInfo" $ \v -> do
users <- v .: "users"
Users <$> A.parseJSON users
-- | The data about a user returned when querying for users in a presence
-- channel.
newtype User
= User
{ userID :: T.Text
}
deriving (Eq, Show)
instance A.FromJSON User where
parseJSON = A.withObject "FullChannelInfo" $ \v -> User <$> v .: "id"