{-| Module : GitHub.REST.Endpoint Maintainer : Brandon Chinn Stability : experimental Portability : portable Define the 'GHEndpoint' helper type for defining a call to a GitHub API endpoint. -} {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} 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