{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK prune, not-home #-}
-- | Provides a higher level interface to the rest functions.
-- Preperly writes to the rate-limit loop. Creates separate
-- MVars for each call
module Discord.Rest
( module Discord.Types
, RestChan(..)
, Request(..)
, writeRestCall
, createHandler
, RestCallException(..)
) where
import Prelude hiding (log)
import Data.Either (fromRight)
import Data.Aeson (FromJSON, eitherDecode)
import Control.Concurrent.Chan
import Control.Concurrent.MVar
import Control.Concurrent (forkIO, ThreadId)
import qualified Data.ByteString.Lazy.Char8 as QL
import Discord.Types
import Discord.Rest.HTTP
newtype RestChan = RestChan (Chan (String, JsonRequest,
MVar (Either RestCallException QL.ByteString)))
-- | Starts the http request thread. Please only call this once
createHandler :: Auth -> Chan String -> IO (RestChan, ThreadId)
createHandler auth log = do
c <- newChan
tid <- forkIO $ restLoop auth c log
pure (RestChan c, tid)
-- | Execute a request blocking until a response is received
writeRestCall :: (Request (r a), FromJSON a) => RestChan -> r a -> IO (Either RestCallException a)
writeRestCall (RestChan c) req = do
m <- newEmptyMVar
writeChan c (majorRoute req, jsonRequest req, m)
r <- readMVar m
pure $ case eitherDecode <$> r of
Right (Right o) -> Right o
Right (Left er) -> Left (RestCallNoParse er (fromRight "" r))
Left e -> Left e