github-rest-1.1.3: src/GitHub/REST/Endpoint.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-|
Module : GitHub.REST.Endpoint
Maintainer : Brandon Chinn <brandonchinn178@gmail.com>
Stability : experimental
Portability : portable
Define the 'GHEndpoint' helper type for defining a call to a GitHub API endpoint.
-}
module GitHub.REST.Endpoint (
GHEndpoint (..),
EndpointVals,
GitHubData,
endpointPath,
renderMethod,
) where
import Data.Maybe (fromMaybe)
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid ((<>))
#endif
import Data.Text (Text)
import qualified Data.Text as Text
import Network.HTTP.Types (Method, StdMethod, renderStdMethod)
import GitHub.REST.KeyValue (KeyValue, kvToText)
type EndpointVals = [KeyValue]
type GitHubData = [KeyValue]
-- | A call to a GitHub API endpoint.
data GHEndpoint = GHEndpoint
{ method :: StdMethod
, endpoint :: Text
-- ^ The GitHub API endpoint, with colon-prefixed components that will be replaced; e.g.
-- @"\/users\/:username\/repos"@
, endpointVals :: EndpointVals
-- ^ Key-value pairs to replace colon-prefixed components in 'endpoint'; e.g.
-- @[ "username" := ("alice" :: Text) ]@
, ghData :: GitHubData
-- ^ Key-value pairs to send in the request body; e.g.
-- @[ "sort" := ("created" :: Text), "direction" := ("asc" :: Text) ]@
}
-- | Return the endpoint path, populated by the values in 'endpointVals'.
endpointPath :: GHEndpoint -> Text
endpointPath GHEndpoint{..} = Text.intercalate "/" . map populate . Text.splitOn "/" $ endpoint
where
values = map kvToText endpointVals
populate t = case Text.uncons t of
Just (':', key) ->
fromMaybe
(fail' $ "Could not find value for key '" <> key <> "'")
$ lookup key values
_ -> t
fail' msg = error . Text.unpack $ msg <> ": " <> endpoint
-- | Render the method of the endpoint.
renderMethod :: GHEndpoint -> Method
renderMethod = renderStdMethod . method