{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UnicodeSyntax #-}

-- | HTTP module abstracts over HTTP requests to the external world.
--
-- This module follows the [Handle pattern](https://jaspervdj.be/posts/2018-03-08-handle-pattern.html).
--
-- > import qualified Imm.HTTP as HTTP
module Imm.HTTP (
  module Imm.HTTP,
  module Network.HTTP.Client,
)
where

-- {{{ Imports
import Imm.Logger hiding (Handle)
import qualified Imm.Logger as Logger
import Imm.Pretty
import Network.HTTP.Client
import Pipes.Core
import URI.ByteString

-- }}}

-- * Types

-- | Handle to perform GET HTTP requests.
newtype Handle m = Handle
  { forall (m :: * -> *).
Handle m
-> forall a.
   URI -> (Response (Producer ByteString m ()) -> m a) -> m a
_withGet   a. URI  (Response (Producer ByteString m ())  m a)  m a
  }

-- * Primitives

-- | Simple wrapper around '_withGet' that also logs the requested URI.
withGet  Monad m  Logger.Handle m  Handle m  URI  (Response (Producer ByteString m ())  m a)  m a
withGet :: forall (m :: * -> *) a.
Monad m =>
Handle m
-> Handle m
-> URI
-> (Response (Producer ByteString m ()) -> m a)
-> m a
withGet Handle m
logger Handle m
handle URI
uri Response (Producer ByteString m ()) -> m a
f = do
  Handle m -> LogLevel -> Doc AnsiStyle -> m ()
forall (m :: * -> *). Handle m -> LogLevel -> Doc AnsiStyle -> m ()
log Handle m
logger LogLevel
Info (Doc AnsiStyle -> m ()) -> Doc AnsiStyle -> m ()
forall a b. (a -> b) -> a -> b
$ Doc AnsiStyle
"GET" Doc AnsiStyle -> Doc AnsiStyle -> Doc AnsiStyle
forall ann. Doc ann -> Doc ann -> Doc ann
<+> URI -> Doc AnsiStyle
forall a b. URIRef a -> Doc b
prettyURI URI
uri
  Handle m
-> forall a.
   URI -> (Response (Producer ByteString m ()) -> m a) -> m a
forall (m :: * -> *).
Handle m
-> forall a.
   URI -> (Response (Producer ByteString m ()) -> m a) -> m a
_withGet Handle m
handle URI
uri Response (Producer ByteString m ()) -> m a
f