{-# LANGUAGE AllowAmbiguousTypes #-}

-- |
-- Module      : Amazonka.Env.Hooks
-- Copyright   : (c) 2023 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
-- Stability   : highly experimental
-- Portability : non-portable (GHC extensions)
--
-- Hooks carried within an 'Env', allowing ad-hoc injection of
-- different behaviour during Amazonka's request/response cycle.
-- Hooks are currently experimental, but Amazonka uses the 'Hooks' API
-- to implement its default logging, and you can add your own
-- behaviour here as well. Some examples of things hooks can do:
--
-- * Log all requests Amazonka makes to a separate log, in order to
--   audit which IAM permissions your program actually needs
--   (see 'requestHook');
--
--   @
--   {-# LANGAUGE OverloadedLabels, ScopedTypeVariables, TypeApplications #-}
--   import Amazonka
--   import Amazonka.Env.Hooks
--   import Data.Generics.Labels ()
--   import Data.Typeable (typeRep)
--
--   main :: IO ()
--   main = do
--     -- Use 'Data.Typeable.typeRep' to capture a `TypeRep` of the request type,
--     -- so we know the request type to log. Note the `(req :: req)`
--     -- argument to the lambda, which captures the type of `req` as
--     -- a type variable `req` (needs `-XScopedTypeVariables`).
--     env <- newEnv discover
--       \<&\> #hooks %~ 'requestHook'
--         ('addRequestHook' $ \\_env (req :: req) -> req <$ logRequest ('typeRep' (Proxy @req)))
--     ...
--
--   logRequest :: AWSRequest a => a -> IO ()
--   logRequest = ...
--   @
--
-- * Inject a [Trace ID for AWS X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader),
--   into each request before it is signed and sent
--   (see 'configuredRequestHook'); and
--
--   @
--   {-# LANGAUGE OverloadedLabels #-}
--   import Amazonka
--   import Amazonka.Env.Hooks
--   import Data.Generics.Labels ()
--
--   main :: IO ()
--   main = do
--     env <- newEnv discover
--       \<&\> #hooks %~ 'configuredRequestHook'
--         ('addConfiguredRequestHook' $ \\_env req -> req & #headers %~ addXRayIdHeader)
--     ...
--
--   -- The actual header would normally come from whatever calls into your program,
--   -- or you would randomly generate one yourself (hooks run in 'IO').
--   addXRayIdHeader :: ['Network.HTTP.Types.Header'] -> ['Network.HTTP.Types.Header']
--   addXRayIdHeader = ...
--   @
--
-- * Selectively silence certain expected errors, such as DynamoDB's
--   @ConditionalCheckFailedException@ ('errorHook' and 'silenceError')
--
--   @
--   {-# LANGAUGE OverloadedLabels #-}
--   import Amazonka
--   import Amazonka.Env.Hooks
--   import qualified Amazonka.DynamoDB as DynamoDB
--   import Data.Generics.Labels ()
--
--   main :: IO ()
--   main = do
--     env <- newEnv discover
--     putItemResponse <- runResourceT $
--       send
--         (env & #hooks %~ 'errorHook'
--           ('silenceError' DynamoDB._ConditionalCheckFailedException))
--         (DynamoDB.newPutItem ...)
--     ...
--   @
--
-- =Function Conventions
--
-- * Functions named @...Hook@ ('requestHook', etc.) are intended for
--   use with lens operators: partially apply them to get a function
--   @'Hooks' -> 'Hooks'@ that can go on the RHS of @(%~)@ (the lens
--   modify function). Use functions like 'addRequestHookFor' to
--   selectively adjust the hook at a particular field.
--
-- * Function names ending in @For@ ('addRequestHookFor',
--   'addConfiguredRequestHookFor', 'removeRequestHooksFor', ...) are
--   designed to work on a single AWS request type. You will need to
--   pin this type with a type application in @remove...HooksFor@
--   functions, and you may want to do so in @add...HooksFor@
--   functions for consistency.
--
-- =Request/Response Flow
--
-- The request/response flow for a standard 'Amazonka.send' looks like
-- this:
--
-- @
--     send (req :: 'AWSRequest' a => a)
--                  |
--                  V
--         Run Hook: request
--                  |
--                  V
-- Amazonka: configure req into "Request a"
--  (Amazonka-specific HTTP request type)
--                  |
--                  V
--     Run Hook: configuredRequest
--                  |
--                  V
-- Amazonka: sign request, turn into standard
--     Network.HTTP.Client.'Network.HTTP.Client.Request'
--                  |
--                  +-<---------------------------------.
--                  V                                   |
--     Run Hook: signedRequest                          |
--                  |                                   |
--                  V                                   |
--     Run Hook: clientRequest                          |
--                  |                                   |
--                  V                                   |
--     Amazonka: send request to AWS           Run Hook: requestRetry
--                  |                                   ^
--                  V                                   |
--     Run Hook: clientResponse                         |
--                  |                                   |
--                  V                                   |
--     Run Hook: rawResponseBody                        |
--                  |                                   |
--                  V                                   |
--     Amazonka: was error? ------------------.         |
--                  |            Yes          |         |
--                  |                         V         |
--                  | No               Run Hook: error  |
--                  |                    ('NotFinal')     |
--                  |                         |         |
--                  +-<-----------------------\'         |
--                  V                                   |
--     Amazonka: should retry? -------------------------\'
--                  |            Yes
--                  | No
--                  V
--     Amazonka: was error? ------------------.
--                  |            Yes          |
--                  |                         V
--                  | No                      |
--                  |                         |
--     Run Hook: response              Run Hook: error
--                  |                     ('Final')
--                  |                         |
--                  V                         |
--     Amazonka: parse response               |
--                  |                         |
--                  +-<-----------------------\'
--                  V
--     Amazonka: return result
-- @
module Amazonka.Env.Hooks
  ( Hook,
    Hook_,
    Hooks (..),
    Finality (..),

    -- * Updating members of 'Hooks'
    requestHook,
    waitHook,
    configuredRequestHook,
    signedRequestHook,
    clientRequestHook,
    clientResponseHook,
    rawResponseBodyHook,
    requestRetryHook,
    awaitRetryHook,
    responseHook,
    errorHook,

    -- * Composing hooks

    -- ** Functions for specific field hooks

    -- *** @requestHook@
    addRequestHook,
    addRequestHookFor,
    removeRequestHooksFor,

    -- *** @configuredRequestHook@
    addConfiguredRequestHook,
    addConfiguredRequestHookFor,
    removeConfiguredRequestHooksFor,

    -- *** @waitHook@
    addWaitHook,
    addWaitHookFor,
    removeWaitHooksFor,

    -- *** @signedRequestHook@
    addSignedRequestHook,
    addSignedRequestHookFor,
    removeSignedRequestHooksFor,

    -- *** @clientRequestHook@
    addClientRequestHook,
    removeClientRequestHooks,

    -- *** @clientResponseHook@
    addClientResponseHook,
    addClientResponseHookFor,
    removeClientResponseHooksFor,

    -- *** @rawResponseBodyHook@
    addRawResponseBodyHook,
    removeRawResponseBodyHooks,

    -- *** @requestRetryHook@
    addRequestRetryHook,
    addRequestRetryHookFor,
    removeRequestRetryHooksFor,

    -- *** @awaitRetryHook@
    addAwaitRetryHook,
    addAwaitRetryHookFor,
    removeAwaitRetryHooksFor,

    -- *** @responseHook@
    addResponseHook,
    addResponseHookFor,
    removeResponseHooksFor,

    -- *** @errorHook@
    addErrorHook,
    addErrorHookFor,
    silenceError,
    removeErrorHooksFor,

    -- ** Functions for any hook
    noHook,
    noHook_,

    -- * Building 'Hooks'
    addLoggingHooks,
    noHooks,

    -- * Deprecated functions
    addHook,
    addHook_,
    addAWSRequestHook,
    addAWSRequestHook_,
    addHookFor,
    addHookFor_,
    removeHooksFor,
    removeHooksFor_,
  )
where

import Amazonka.Core.Lens.Internal (Getting, has)
import {-# SOURCE #-} Amazonka.Env (Env' (..))
import Amazonka.Logger (build, logDebug, logError, logTrace)
import Amazonka.Prelude hiding (error)
import Amazonka.Types
  ( AWSRequest,
    AWSResponse,
    ClientRequest,
    ClientResponse,
    Error,
    Request,
    Signed (..),
  )
import Amazonka.Waiter (Accept, Wait (..))
import qualified Control.Retry as Retry
import Data.List (intersperse)
import Data.Monoid (Any)
import Data.Typeable (Typeable, eqT, (:~:) (..))

-- | A hook that returns an updated version of its arguments.
--
-- @since 2.0
type Hook a = forall withAuth. Env' withAuth -> a -> IO a

-- | A hook that cannot return an updated version of its argument.
--
-- These hooks respond to some event but lack the ability to change
-- Amazonka's behaviour; either because it is unsafe to do so, or
-- because it is difficult to do anything meaningful with the updated
-- value.
--
-- @since 2.0
type Hook_ a = forall withAuth. Env' withAuth -> a -> IO ()

-- | Indicates whether an error hook is potentially going to be
-- retried.
--
-- /See:/ 'error'
--
-- @since 2.0
data Finality = NotFinal | Final
  deriving stock (Finality
Finality -> Finality -> Bounded Finality
forall a. a -> a -> Bounded a
$cminBound :: Finality
minBound :: Finality
$cmaxBound :: Finality
maxBound :: Finality
Bounded, Int -> Finality
Finality -> Int
Finality -> [Finality]
Finality -> Finality
Finality -> Finality -> [Finality]
Finality -> Finality -> Finality -> [Finality]
(Finality -> Finality)
-> (Finality -> Finality)
-> (Int -> Finality)
-> (Finality -> Int)
-> (Finality -> [Finality])
-> (Finality -> Finality -> [Finality])
-> (Finality -> Finality -> [Finality])
-> (Finality -> Finality -> Finality -> [Finality])
-> Enum Finality
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Finality -> Finality
succ :: Finality -> Finality
$cpred :: Finality -> Finality
pred :: Finality -> Finality
$ctoEnum :: Int -> Finality
toEnum :: Int -> Finality
$cfromEnum :: Finality -> Int
fromEnum :: Finality -> Int
$cenumFrom :: Finality -> [Finality]
enumFrom :: Finality -> [Finality]
$cenumFromThen :: Finality -> Finality -> [Finality]
enumFromThen :: Finality -> Finality -> [Finality]
$cenumFromTo :: Finality -> Finality -> [Finality]
enumFromTo :: Finality -> Finality -> [Finality]
$cenumFromThenTo :: Finality -> Finality -> Finality -> [Finality]
enumFromThenTo :: Finality -> Finality -> Finality -> [Finality]
Enum, Finality -> Finality -> Bool
(Finality -> Finality -> Bool)
-> (Finality -> Finality -> Bool) -> Eq Finality
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Finality -> Finality -> Bool
== :: Finality -> Finality -> Bool
$c/= :: Finality -> Finality -> Bool
/= :: Finality -> Finality -> Bool
Eq, Eq Finality
Eq Finality =>
(Finality -> Finality -> Ordering)
-> (Finality -> Finality -> Bool)
-> (Finality -> Finality -> Bool)
-> (Finality -> Finality -> Bool)
-> (Finality -> Finality -> Bool)
-> (Finality -> Finality -> Finality)
-> (Finality -> Finality -> Finality)
-> Ord Finality
Finality -> Finality -> Bool
Finality -> Finality -> Ordering
Finality -> Finality -> Finality
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Finality -> Finality -> Ordering
compare :: Finality -> Finality -> Ordering
$c< :: Finality -> Finality -> Bool
< :: Finality -> Finality -> Bool
$c<= :: Finality -> Finality -> Bool
<= :: Finality -> Finality -> Bool
$c> :: Finality -> Finality -> Bool
> :: Finality -> Finality -> Bool
$c>= :: Finality -> Finality -> Bool
>= :: Finality -> Finality -> Bool
$cmax :: Finality -> Finality -> Finality
max :: Finality -> Finality -> Finality
$cmin :: Finality -> Finality -> Finality
min :: Finality -> Finality -> Finality
Ord, Int -> Finality -> [Char] -> [Char]
[Finality] -> [Char] -> [Char]
Finality -> [Char]
(Int -> Finality -> [Char] -> [Char])
-> (Finality -> [Char])
-> ([Finality] -> [Char] -> [Char])
-> Show Finality
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> Finality -> [Char] -> [Char]
showsPrec :: Int -> Finality -> [Char] -> [Char]
$cshow :: Finality -> [Char]
show :: Finality -> [Char]
$cshowList :: [Finality] -> [Char] -> [Char]
showList :: [Finality] -> [Char] -> [Char]
Show, (forall x. Finality -> Rep Finality x)
-> (forall x. Rep Finality x -> Finality) -> Generic Finality
forall x. Rep Finality x -> Finality
forall x. Finality -> Rep Finality x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Finality -> Rep Finality x
from :: forall x. Finality -> Rep Finality x
$cto :: forall x. Rep Finality x -> Finality
to :: forall x. Rep Finality x -> Finality
Generic)

-- | The collection of lifecycle hooks stored in an 'Amazonka.Env.Env'.
--
-- @since 2.0
data Hooks = Hooks
  { -- | Called at the start of request processing, before the request
    -- is configured. This is always the first hook that runs, and its
    -- argument is usually a request record type like @amazonka-s3@'s
    -- @GetObjectRequest@.
    Hooks -> forall a. AWSRequest a => Hook a
request :: forall a. (AWSRequest a) => Hook a,
    -- | Called after the request has been configured into an abstract
    -- HTTP request, but before it is converted to a signed
    -- @Network.HTTP.Client.'Network.HTTP.Client.Request'@.
    --
    -- If you want to add additional headers (e.g., a
    -- [Trace ID for AWS X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader)),
    -- do it with this hook.
    Hooks -> forall a. AWSRequest a => Hook (Request a)
configuredRequest :: forall a. (AWSRequest a) => Hook (Request a),
    -- | Called at the start of waiter processing, just after the
    -- request is configured.
    Hooks -> forall a. AWSRequest a => Hook (Wait a)
wait :: forall a. (AWSRequest a) => Hook (Wait a),
    -- | Called just after a request is signed, containing signature
    -- metadata and a
    -- @Network.HTTP.Client.'Network.HTTP.Client.Request'@.
    Hooks -> forall a. AWSRequest a => Hook_ (Signed a)
signedRequest :: forall a. (AWSRequest a) => Hook_ (Signed a),
    -- | Called on a
    -- @Network.HTTP.Client.'Network.HTTP.Client.Request'@, just
    -- before it is sent. While you can retrieve a 'ClientRequest'
    -- from the @signedRequest@ hook, this hook captures unsigned
    -- requests too.
    --
    -- Changing the contents of a signed request is highly likely to
    -- break its signature.
    Hooks -> Hook ClientRequest
clientRequest :: Hook ClientRequest,
    -- | Called on the raw
    -- @Network.HTTP.Client.'Network.HTTP.Client.Response'@, as soon
    -- as it comes back from the HTTP client. The body is replaced
    -- with @()@ to prevent its accidental consumption by hooks.
    Hooks
-> forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse ::
      forall a.
      (AWSRequest a) =>
      Hook_ (Request a, ClientResponse ()),
    -- | Called on the raw response body, after it has been sunk from
    -- the @Network.HTTP.Client.'Network.HTTP.Client.Response'@.
    Hooks -> Hook ByteStringLazy
rawResponseBody :: Hook ByteStringLazy,
    -- | Called when Amazonka decides to retry a failed request. The
    -- 'Text' argument is an error code like @"http_error"@ or
    -- @"request_throttled_exception"@. Check the retry check function
    -- for your particular 'Service', usually found somewhere like
    -- @Amazonka.S3.Types.defaultService@.
    Hooks
-> forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry ::
      forall a.
      (AWSRequest a) =>
      Hook_ (Request a, Text, Retry.RetryStatus),
    -- | Called when Amazonka decides to retry a request while
    -- resolving an 'Amazonka.await' operation.
    Hooks
-> forall a.
   AWSRequest a =>
   Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry ::
      forall a.
      (AWSRequest a) =>
      Hook_ (Request a, Wait a, Accept, Retry.RetryStatus),
    -- | Called when a response from AWS is successfully
    -- deserialised. Because the 'AWSResponse' type family is not
    -- injective, we include the original request.
    Hooks
-> forall a.
   AWSRequest a =>
   Hook_ (Request a, ClientResponse (AWSResponse a))
response ::
      forall a.
      (AWSRequest a) =>
      Hook_ (Request a, ClientResponse (AWSResponse a)),
    -- | Called whenever an AWS request returns an 'Error', even when
    -- the corresponding request is retried.
    --
    -- On the final error after all retries, this hook will be called
    -- twice: once with @NotFinal@ and once with @Final@. This
    -- behavior may change in a future version.
    Hooks
-> forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error ::
      forall a.
      (AWSRequest a) =>
      Hook_ (Finality, Request a, Error)
  }

-- | @since 2.0
requestHook ::
  (forall a. (AWSRequest a) => Hook a -> Hook a) ->
  Hooks ->
  Hooks
requestHook :: (forall a. AWSRequest a => Hook a -> Hook a) -> Hooks -> Hooks
requestHook forall a. AWSRequest a => Hook a -> Hook a
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook a
request :: Hooks -> forall a. AWSRequest a => Hook a
request :: forall a. AWSRequest a => Hook a
request} =
  Hooks
hooks {request = f request}
{-# INLINE requestHook #-}

-- | @since 2.0
waitHook ::
  (forall a. (AWSRequest a) => Hook (Wait a) -> Hook (Wait a)) ->
  Hooks ->
  Hooks
waitHook :: (forall a. AWSRequest a => Hook (Wait a) -> Hook (Wait a))
-> Hooks -> Hooks
waitHook forall a. AWSRequest a => Hook (Wait a) -> Hook (Wait a)
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook (Wait a)
wait :: Hooks -> forall a. AWSRequest a => Hook (Wait a)
wait :: forall a. AWSRequest a => Hook (Wait a)
wait} =
  Hooks
hooks {wait = f wait}
{-# INLINE waitHook #-}

-- | @since 2.0
configuredRequestHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook (Request a) ->
    Hook (Request a)
  ) ->
  Hooks ->
  Hooks
configuredRequestHook :: (forall a. AWSRequest a => Hook (Request a) -> Hook (Request a))
-> Hooks -> Hooks
configuredRequestHook forall a. AWSRequest a => Hook (Request a) -> Hook (Request a)
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook (Request a)
configuredRequest :: Hooks -> forall a. AWSRequest a => Hook (Request a)
configuredRequest :: forall a. AWSRequest a => Hook (Request a)
configuredRequest} =
  Hooks
hooks {configuredRequest = f configuredRequest}
{-# INLINE configuredRequestHook #-}

-- | @since 2.0
signedRequestHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook_ (Signed a) ->
    Hook_ (Signed a)
  ) ->
  Hooks ->
  Hooks
signedRequestHook :: (forall a. AWSRequest a => Hook_ (Signed a) -> Hook_ (Signed a))
-> Hooks -> Hooks
signedRequestHook forall a. AWSRequest a => Hook_ (Signed a) -> Hook_ (Signed a)
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook_ (Signed a)
signedRequest :: Hooks -> forall a. AWSRequest a => Hook_ (Signed a)
signedRequest :: forall a. AWSRequest a => Hook_ (Signed a)
signedRequest} =
  Hooks
hooks {signedRequest = f signedRequest}
{-# INLINE signedRequestHook #-}

-- | @since 2.0
clientRequestHook ::
  (Hook ClientRequest -> Hook ClientRequest) ->
  Hooks ->
  Hooks
clientRequestHook :: (Hook ClientRequest -> Hook ClientRequest) -> Hooks -> Hooks
clientRequestHook Hook ClientRequest -> Hook ClientRequest
f hooks :: Hooks
hooks@Hooks {Hook ClientRequest
clientRequest :: Hooks -> Hook ClientRequest
clientRequest :: Hook ClientRequest
clientRequest} =
  Hooks
hooks {clientRequest = f clientRequest}
{-# INLINE clientRequestHook #-}

-- | @since 2.0
clientResponseHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook_ (Request a, ClientResponse ()) ->
    Hook_ (Request a, ClientResponse ())
  ) ->
  Hooks ->
  Hooks
clientResponseHook :: (forall a.
 AWSRequest a =>
 Hook_ (Request a, ClientResponse ())
 -> Hook_ (Request a, ClientResponse ()))
-> Hooks -> Hooks
clientResponseHook forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse ())
-> Hook_ (Request a, ClientResponse ())
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse :: Hooks
-> forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse :: forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse} =
  Hooks
hooks {clientResponse = f clientResponse}
{-# INLINE clientResponseHook #-}

-- | @since 2.0
rawResponseBodyHook ::
  (Hook ByteStringLazy -> Hook ByteStringLazy) ->
  Hooks ->
  Hooks
rawResponseBodyHook :: (Hook ByteStringLazy -> Hook ByteStringLazy) -> Hooks -> Hooks
rawResponseBodyHook Hook ByteStringLazy -> Hook ByteStringLazy
f hooks :: Hooks
hooks@Hooks {Hook ByteStringLazy
rawResponseBody :: Hooks -> Hook ByteStringLazy
rawResponseBody :: Hook ByteStringLazy
rawResponseBody} =
  Hooks
hooks {rawResponseBody = f rawResponseBody}
{-# INLINE rawResponseBodyHook #-}

-- | @since 2.0
requestRetryHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook_ (Request a, Text, Retry.RetryStatus) ->
    Hook_ (Request a, Text, Retry.RetryStatus)
  ) ->
  Hooks ->
  Hooks
requestRetryHook :: (forall a.
 AWSRequest a =>
 Hook_ (Request a, Text, RetryStatus)
 -> Hook_ (Request a, Text, RetryStatus))
-> Hooks -> Hooks
requestRetryHook forall a.
AWSRequest a =>
Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request a, Text, RetryStatus)
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry :: Hooks
-> forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry :: forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry} =
  Hooks
hooks {requestRetry = f requestRetry}
{-# INLINE requestRetryHook #-}

-- | @since 2.0
awaitRetryHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook_ (Request a, Wait a, Accept, Retry.RetryStatus) ->
    Hook_ (Request a, Wait a, Accept, Retry.RetryStatus)
  ) ->
  Hooks ->
  Hooks
awaitRetryHook :: (forall a.
 AWSRequest a =>
 Hook_ (Request a, Wait a, Accept, RetryStatus)
 -> Hook_ (Request a, Wait a, Accept, RetryStatus))
-> Hooks -> Hooks
awaitRetryHook forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request a, Wait a, Accept, RetryStatus)
f hooks :: Hooks
hooks@Hooks {forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry :: Hooks
-> forall a.
   AWSRequest a =>
   Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry :: forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry} =
  Hooks
hooks {awaitRetry = f awaitRetry}
{-# INLINE awaitRetryHook #-}

-- | @since 2.0
responseHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook_ (Request a, ClientResponse (AWSResponse a)) ->
    Hook_ (Request a, ClientResponse (AWSResponse a))
  ) ->
  Hooks ->
  Hooks
responseHook :: (forall a.
 AWSRequest a =>
 Hook_ (Request a, ClientResponse (AWSResponse a))
 -> Hook_ (Request a, ClientResponse (AWSResponse a)))
-> Hooks -> Hooks
responseHook forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request a, ClientResponse (AWSResponse a))
f hooks :: Hooks
hooks@Hooks {forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse (AWSResponse a))
response :: Hooks
-> forall a.
   AWSRequest a =>
   Hook_ (Request a, ClientResponse (AWSResponse a))
response :: forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse (AWSResponse a))
response} =
  Hooks
hooks {response = f response}
{-# INLINE responseHook #-}

-- | @since 2.0
errorHook ::
  ( forall a.
    (AWSRequest a) =>
    Hook_ (Finality, Request a, Error) ->
    Hook_ (Finality, Request a, Error)
  ) ->
  Hooks ->
  Hooks
errorHook :: (forall a.
 AWSRequest a =>
 Hook_ (Finality, Request a, Error)
 -> Hook_ (Finality, Request a, Error))
-> Hooks -> Hooks
errorHook forall a.
AWSRequest a =>
Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
f hooks :: Hooks
hooks@Hooks {forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error :: Hooks
-> forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error :: forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error} =
  Hooks
hooks {error = f error}
{-# INLINE errorHook #-}

-- | Add a hook for every AWS request type. Designed to be used with
-- 'requestHook'.
--
-- @
-- -- Example: A hook modification that logs every AWS request,
-- -- where `logRequest :: AWSRequest a => Hook a`.
-- requestHook (addRequestHook logRequest) :: Hooks -> Hooks
-- @
--
-- @since 2.1
addRequestHook :: (AWSRequest a) => Hook a -> Hook a -> Hook a
addRequestHook :: forall a. AWSRequest a => Hook a -> Hook a -> Hook a
addRequestHook = Hook a -> Hook a -> Env' withAuth -> a -> IO a
Hook a -> Hook a -> Hook a
forall a. Hook a -> Hook a -> Hook a
addHook

-- | Add a hook for one specific AWS request type. Designed to be used
-- with 'requestHook'.
--
-- @
-- -- Example: Run @getObjectRequestHook@ on anything that is a @GetObjectRequest@
-- -- Assumes getObjectRequestHook :: Hook GetObjectRequest
-- requestHook (addRequestHookFor getObjectRequestHook) :: Hooks -> Hooks
-- @
--
-- @since 2.1
addRequestHookFor ::
  forall a b. (AWSRequest a, AWSRequest b) => Hook a -> Hook b -> Hook b
addRequestHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook a -> Hook b -> Hook b
addRequestHookFor = Hook a -> Hook b -> Env' withAuth -> b -> IO b
Hook a -> Hook b -> Hook b
forall a b. (Typeable a, Typeable b) => Hook a -> Hook b -> Hook b
addHookFor

-- | Remove all hooks for one AWS request type. Designed to be used
-- with 'requestHook'.
--
-- @
-- -- Example: Don't run 'request' hooks on a @GetObjectRequest@:
-- requestHook (removeRequestHooksFor @GetObjectRequest) :: Hooks -> Hooks
-- @
--
-- @since 2.1
removeRequestHooksFor ::
  forall a b. (AWSRequest a, AWSRequest b) => Hook b -> Hook b
removeRequestHooksFor :: forall a b. (AWSRequest a, AWSRequest b) => Hook b -> Hook b
removeRequestHooksFor = forall a b. (Typeable a, Typeable b) => Hook b -> Hook b
removeHooksFor @a

-- | Add a hook for every configured AWS request type. Designed
-- to be used with 'configuredRequestHook'.
--
-- @since 2.1
addConfiguredRequestHook ::
  (AWSRequest a) => Hook (Request a) -> Hook (Request a) -> Hook (Request a)
addConfiguredRequestHook :: forall a.
AWSRequest a =>
Hook (Request a) -> Hook (Request a) -> Hook (Request a)
addConfiguredRequestHook = Hook (Request a)
-> Hook (Request a) -> Env' withAuth -> Request a -> IO (Request a)
Hook (Request a) -> Hook (Request a) -> Hook (Request a)
forall a. Hook a -> Hook a -> Hook a
addHook

-- | Add a hook for one specific configured AWS request type. Designed
-- to be used with 'configuredRequestHook'.
--
-- @since 2.1
addConfiguredRequestHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook (Request a) ->
  Hook (Request b) ->
  Hook (Request b)
addConfiguredRequestHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook (Request a) -> Hook (Request b) -> Hook (Request b)
addConfiguredRequestHookFor = Hook (Request a)
-> Hook (Request b) -> Env' withAuth -> Request b -> IO (Request b)
Hook (Request a) -> Hook (Request b) -> Hook (Request b)
forall a b. (Typeable a, Typeable b) => Hook a -> Hook b -> Hook b
addHookFor

-- | Remove all hooks for one specific type of configured
-- request. Designed to be used with 'configuredRequestHook'.
--
-- @since 2.1
removeConfiguredRequestHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook (Request b) ->
  Hook (Request b)
removeConfiguredRequestHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook (Request b) -> Hook (Request b)
removeConfiguredRequestHooksFor = forall a b. (Typeable a, Typeable b) => Hook b -> Hook b
removeHooksFor @(Request a)

-- | Add a hook for every @'Wait' a@ configuration. Designed to
-- be used with 'waitHook'.
--
-- @since 2.1
addWaitHook ::
  (AWSRequest a) => Hook (Wait a) -> Hook (Wait a) -> Hook (Wait a)
addWaitHook :: forall a.
AWSRequest a =>
Hook (Wait a) -> Hook (Wait a) -> Hook (Wait a)
addWaitHook = Hook (Wait a)
-> Hook (Wait a) -> Env' withAuth -> Wait a -> IO (Wait a)
Hook (Wait a) -> Hook (Wait a) -> Hook (Wait a)
forall a. Hook a -> Hook a -> Hook a
addHook

-- | Add a hook for one specific @'Wait' a@ configuration. Designed to
-- be used with 'waitHook'.
--
-- @since 2.1
addWaitHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook (Wait a) ->
  Hook (Wait b) ->
  Hook (Wait b)
addWaitHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook (Wait a) -> Hook (Wait b) -> Hook (Wait b)
addWaitHookFor = Hook (Wait a)
-> Hook (Wait b) -> Env' withAuth -> Wait b -> IO (Wait b)
Hook (Wait a) -> Hook (Wait b) -> Hook (Wait b)
forall a b. (Typeable a, Typeable b) => Hook a -> Hook b -> Hook b
addHookFor

-- | Remove all hooks for one specific type of @'Wait' a@. Designed to
-- be used with 'waitHook'.
--
-- @since 2.1
removeWaitHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook (Wait b) ->
  Hook (Wait b)
removeWaitHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook (Wait b) -> Hook (Wait b)
removeWaitHooksFor = forall a b. (Typeable a, Typeable b) => Hook b -> Hook b
removeHooksFor @(Wait a)

-- | Add a hook for every @'Signed' a@ request. Designed to be used
-- with 'signedRequestHook'.
--
-- @since 2.1
addSignedRequestHook ::
  (AWSRequest a) => Hook_ (Signed a) -> Hook_ (Signed a) -> Hook_ (Signed a)
addSignedRequestHook :: forall a.
AWSRequest a =>
Hook_ (Signed a) -> Hook_ (Signed a) -> Hook_ (Signed a)
addSignedRequestHook = Hook_ (Signed a)
-> Hook_ (Signed a) -> Env' withAuth -> Signed a -> IO ()
Hook_ (Signed a) -> Hook_ (Signed a) -> Hook_ (Signed a)
forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_

-- | Add a hook for one specific @'Signed' a@ request type. Designed
-- to be used with 'signedRequestHook'.
--
-- @since 2.1
addSignedRequestHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Signed a) ->
  Hook_ (Signed b) ->
  Hook_ (Signed b)
addSignedRequestHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Signed a) -> Hook_ (Signed b) -> Hook_ (Signed b)
addSignedRequestHookFor = Hook_ (Signed a)
-> Hook_ (Signed b) -> Env' withAuth -> Signed b -> IO ()
Hook_ (Signed a) -> Hook_ (Signed b) -> Hook_ (Signed b)
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_

-- | Remove all hooks for one specific type of @'Signed' a@
-- request. Designed to be used with 'signedRequestHook'.
--
-- @since 2.1
removeSignedRequestHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Signed b) ->
  Hook_ (Signed b)
removeSignedRequestHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Signed b) -> Hook_ (Signed b)
removeSignedRequestHooksFor = forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ @(Signed a)

-- | Add a hook for 'ClientRequest'. This is an alias for 'addHook',
-- provided for consistency and designed to be used with
-- 'clientRequestHook'.
--
-- @since 2.1
addClientRequestHook ::
  Hook ClientRequest -> Hook ClientRequest -> Hook ClientRequest
addClientRequestHook :: Hook ClientRequest -> Hook ClientRequest -> Hook ClientRequest
addClientRequestHook = Hook ClientRequest
-> Hook ClientRequest
-> Env' withAuth
-> ClientRequest
-> IO ClientRequest
Hook ClientRequest -> Hook ClientRequest -> Hook ClientRequest
forall a. Hook a -> Hook a -> Hook a
addHook

-- | Remove all hooks for 'ClientRequest'. This is an alias for
-- 'noHook', provided for consistency and designed to be used with
-- 'clientRequestHook'.
--
-- @since 2.1
removeClientRequestHooks :: Hook ClientRequest -> Hook ClientRequest
removeClientRequestHooks :: Hook ClientRequest -> Hook ClientRequest
removeClientRequestHooks = Hook ClientRequest
-> Env' withAuth -> ClientRequest -> IO ClientRequest
Hook ClientRequest -> Hook ClientRequest
forall a. Hook a -> Hook a
noHook

-- | Add a hook for every type of client response. Designed to
-- be used with 'clientResponseHook'.
--
-- @since 2.1
addClientResponseHook ::
  (AWSRequest a) =>
  Hook_ (Request a, ClientResponse ()) ->
  Hook_ (Request a, ClientResponse ()) ->
  Hook_ (Request a, ClientResponse ())
addClientResponseHook :: forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse ())
-> Hook_ (Request a, ClientResponse ())
-> Hook_ (Request a, ClientResponse ())
addClientResponseHook = Hook_ (Request a, ClientResponse ())
-> Hook_ (Request a, ClientResponse ())
-> Env' withAuth
-> (Request a, ClientResponse ())
-> IO ()
Hook_ (Request a, ClientResponse ())
-> Hook_ (Request a, ClientResponse ())
-> Hook_ (Request a, ClientResponse ())
forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_

-- | Add a hook for one specific type of client response. Designed to
-- be used with 'clientResponseHook'.
--
-- @since 2.1
addClientResponseHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request a, ClientResponse ()) ->
  Hook_ (Request b, ClientResponse ()) ->
  Hook_ (Request b, ClientResponse ())
addClientResponseHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request a, ClientResponse ())
-> Hook_ (Request b, ClientResponse ())
-> Hook_ (Request b, ClientResponse ())
addClientResponseHookFor = Hook_ (Request a, ClientResponse ())
-> Hook_ (Request b, ClientResponse ())
-> Env' withAuth
-> (Request b, ClientResponse ())
-> IO ()
Hook_ (Request a, ClientResponse ())
-> Hook_ (Request b, ClientResponse ())
-> Hook_ (Request b, ClientResponse ())
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_

-- | Remove all hooks for one specific type of client
-- response. Designed to be used with 'clientResponseHook'.
--
-- @since 2.1
removeClientResponseHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request b, ClientResponse ()) ->
  Hook_ (Request b, ClientResponse ())
removeClientResponseHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request b, ClientResponse ())
-> Hook_ (Request b, ClientResponse ())
removeClientResponseHooksFor = forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ @(Request a, ClientResponse ())

-- | Add a hook for the raw response body. This is an alias for
-- 'addHook', provided for consistency and designed to be used with
-- 'rawResponseBodyHook'.
--
-- @since 2.1
addRawResponseBodyHook ::
  Hook ByteStringLazy -> Hook ByteStringLazy -> Hook ByteStringLazy
addRawResponseBodyHook :: Hook ByteStringLazy -> Hook ByteStringLazy -> Hook ByteStringLazy
addRawResponseBodyHook = Hook ByteStringLazy
-> Hook ByteStringLazy
-> Env' withAuth
-> ByteStringLazy
-> IO ByteStringLazy
Hook ByteStringLazy -> Hook ByteStringLazy -> Hook ByteStringLazy
forall a. Hook a -> Hook a -> Hook a
addHook

-- | Remove all hooks for the raw response body. This is an alias for
-- 'noHook', provided for consistency and designed to be used with
-- 'rawResponseBodyHook'.
--
-- @since 2.1
removeRawResponseBodyHooks :: Hook ByteStringLazy -> Hook ByteStringLazy
removeRawResponseBodyHooks :: Hook ByteStringLazy -> Hook ByteStringLazy
removeRawResponseBodyHooks = Hook ByteStringLazy
-> Env' withAuth -> ByteStringLazy -> IO ByteStringLazy
Hook ByteStringLazy -> Hook ByteStringLazy
forall a. Hook a -> Hook a
noHook

-- | Add a request retry hook for every AWS request type. Designed to
-- be used with 'requestRetryHook'.
--
-- @since 2.1
addRequestRetryHook ::
  (AWSRequest a) =>
  Hook_ (Request a, Text, Retry.RetryStatus) ->
  Hook_ (Request a, Text, Retry.RetryStatus) ->
  Hook_ (Request a, Text, Retry.RetryStatus)
addRequestRetryHook :: forall a.
AWSRequest a =>
Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request a, Text, RetryStatus)
addRequestRetryHook = Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request a, Text, RetryStatus)
-> Env' withAuth
-> (Request a, Text, RetryStatus)
-> IO ()
Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request a, Text, RetryStatus)
forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_

-- | Add a request retry hook for one specific AWS request
-- type. Designed to be used with 'requestRetryHook'.
--
-- @since 2.1
addRequestRetryHookFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request a, Text, Retry.RetryStatus) ->
  Hook_ (Request b, Text, Retry.RetryStatus) ->
  Hook_ (Request b, Text, Retry.RetryStatus)
addRequestRetryHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request b, Text, RetryStatus)
-> Hook_ (Request b, Text, RetryStatus)
addRequestRetryHookFor = Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request b, Text, RetryStatus)
-> Env' withAuth
-> (Request b, Text, RetryStatus)
-> IO ()
Hook_ (Request a, Text, RetryStatus)
-> Hook_ (Request b, Text, RetryStatus)
-> Hook_ (Request b, Text, RetryStatus)
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_

-- | Remove all request retry hooks for one specific AWS request
-- type. Designed to be used with 'requestRetryHook'.
--
-- @since 2.1
removeRequestRetryHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request b, Text, Retry.RetryStatus) ->
  Hook_ (Request b, Text, Retry.RetryStatus)
removeRequestRetryHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request b, Text, RetryStatus)
-> Hook_ (Request b, Text, RetryStatus)
removeRequestRetryHooksFor =
  forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ @(Request a, Text, Retry.RetryStatus)

-- | Add an await retry hook for every AWS request type. Designed to
-- be used with 'awaitRetryHook'.
--
-- @since 2.1
addAwaitRetryHook ::
  (AWSRequest a) =>
  Hook_ (Request a, Wait a, Accept, Retry.RetryStatus) ->
  Hook_ (Request a, Wait a, Accept, Retry.RetryStatus) ->
  Hook_ (Request a, Wait a, Accept, Retry.RetryStatus)
addAwaitRetryHook :: forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request a, Wait a, Accept, RetryStatus)
addAwaitRetryHook = Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Env' withAuth
-> (Request a, Wait a, Accept, RetryStatus)
-> IO ()
Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request a, Wait a, Accept, RetryStatus)
forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_

-- | Add an await retry hook for a specific AWS request type. Designed
-- to be used with 'awaitRetryHook'.
--
-- @since 2.1
addAwaitRetryHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request a, Wait a, Accept, Retry.RetryStatus) ->
  Hook_ (Request b, Wait b, Accept, Retry.RetryStatus) ->
  Hook_ (Request b, Wait b, Accept, Retry.RetryStatus)
addAwaitRetryHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request b, Wait b, Accept, RetryStatus)
-> Hook_ (Request b, Wait b, Accept, RetryStatus)
addAwaitRetryHookFor = Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request b, Wait b, Accept, RetryStatus)
-> Env' withAuth
-> (Request b, Wait b, Accept, RetryStatus)
-> IO ()
Hook_ (Request a, Wait a, Accept, RetryStatus)
-> Hook_ (Request b, Wait b, Accept, RetryStatus)
-> Hook_ (Request b, Wait b, Accept, RetryStatus)
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_

-- | Remove all await retry hooks for one specific AWS request
-- type. Designed to be used with 'awaitRetryHook'.
--
-- @since 2.1
removeAwaitRetryHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request b, Wait b, Accept, Retry.RetryStatus) ->
  Hook_ (Request b, Wait b, Accept, Retry.RetryStatus)
removeAwaitRetryHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request b, Wait b, Accept, RetryStatus)
-> Hook_ (Request b, Wait b, Accept, RetryStatus)
removeAwaitRetryHooksFor =
  forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ @(Request a, Wait a, Accept, Retry.RetryStatus)

-- | Add a repsonse hook for every AWS request type. Designed to be
-- used with 'responseHook'.
--
-- @since 2.1
addResponseHook ::
  (AWSRequest a) =>
  Hook_ (Request a, ClientResponse (AWSResponse a)) ->
  Hook_ (Request a, ClientResponse (AWSResponse a)) ->
  Hook_ (Request a, ClientResponse (AWSResponse a))
addResponseHook :: forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request a, ClientResponse (AWSResponse a))
addResponseHook = Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request a, ClientResponse (AWSResponse a))
-> Env' withAuth
-> (Request a, ClientResponse (AWSResponse a))
-> IO ()
Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request a, ClientResponse (AWSResponse a))
forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_

-- | Add a repsonse hook for one specific AWS request type. Designed
-- to be used with 'responseHook'.
--
-- @since 2.1
addResponseHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request a, ClientResponse (AWSResponse a)) ->
  Hook_ (Request b, ClientResponse (AWSResponse b)) ->
  Hook_ (Request b, ClientResponse (AWSResponse b))
addResponseHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request b, ClientResponse (AWSResponse b))
-> Hook_ (Request b, ClientResponse (AWSResponse b))
addResponseHookFor = Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request b, ClientResponse (AWSResponse b))
-> Env' withAuth
-> (Request b, ClientResponse (AWSResponse b))
-> IO ()
Hook_ (Request a, ClientResponse (AWSResponse a))
-> Hook_ (Request b, ClientResponse (AWSResponse b))
-> Hook_ (Request b, ClientResponse (AWSResponse b))
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_

-- | Remove all response hooks for one specific AWS request
-- type. Designed to be used with 'responseHook'.
--
-- @since 2.1
removeResponseHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Request b, ClientResponse (AWSResponse b)) ->
  Hook_ (Request b, ClientResponse (AWSResponse b))
removeResponseHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Request b, ClientResponse (AWSResponse b))
-> Hook_ (Request b, ClientResponse (AWSResponse b))
removeResponseHooksFor =
  forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ @(Request a, ClientResponse (AWSResponse a))

-- | Add an error hook for every AWS request type. Designed to be used
-- with 'errorHook'.
--
-- @since 2.1
addErrorHook ::
  (AWSRequest a) =>
  Hook_ (Finality, Request a, Error) ->
  Hook_ (Finality, Request a, Error) ->
  Hook_ (Finality, Request a, Error)
addErrorHook :: forall a.
AWSRequest a =>
Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
addErrorHook = Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
-> Env' withAuth
-> (Finality, Request a, Error)
-> IO ()
Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_

-- | Add an error hook for one specific AWS request type. Designed to
-- be used with 'errorHook'.
--
-- @since 2.1
addErrorHookFor ::
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Finality, Request a, Error) ->
  Hook_ (Finality, Request b, Error) ->
  Hook_ (Finality, Request b, Error)
addErrorHookFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request b, Error)
-> Hook_ (Finality, Request b, Error)
addErrorHookFor = Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request b, Error)
-> Env' withAuth
-> (Finality, Request b, Error)
-> IO ()
Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request b, Error)
-> Hook_ (Finality, Request b, Error)
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_

-- | Run the wrapped hook unless the given 'Fold' or 'Traversal'
-- matches the error. You will probably want to use this with the
-- error matchers defined by each service binding, allowing you to
-- selectively silence specific errors:
--
-- @
-- -- Assuming `env :: Amazonka.Env` and `putRequest :: DynamoDB.PutRequest`,
-- -- this silences a single type of error for a single call:
-- send (env & #hooks %~ errorHook (silenceError DynamoDB._ConditionalCheckFailedException))
-- @
--
-- @
-- 'silenceError' :: Getter Error e     -> 'Hook_' ('Finality', Request a, Error) -> 'Hook_' ('Finality', Request a, Error)
-- 'silenceError' :: Fold Error e       -> 'Hook_' ('Finality', Request a, Error) -> 'Hook_' ('Finality', Request a, Error)
-- 'silenceError' :: Iso' Error e       -> 'Hook_' ('Finality', Request a, Error) -> 'Hook_' ('Finality', Request a, Error)
-- 'silenceError' :: Lens' Error e      -> 'Hook_' ('Finality', Request a, Error) -> 'Hook_' ('Finality', Request a, Error)
-- 'silenceError' :: Traversal' Error e -> 'Hook_' ('Finality', Request a, Error) -> 'Hook_' ('Finality', Request a, Error)
-- @
--
-- @since 2.0
silenceError ::
  Getting Any Error e ->
  Hook_ (Finality, Request a, Error) ->
  Hook_ (Finality, Request a, Error)
silenceError :: forall e a.
Getting Any Error e
-> Hook_ (Finality, Request a, Error)
-> Hook_ (Finality, Request a, Error)
silenceError Getting Any Error e
g Hook_ (Finality, Request a, Error)
oldHook Env' withAuth
env t :: (Finality, Request a, Error)
t@(Finality
_, Request a
_, Error
err) =
  if Getting Any Error e -> Error -> Bool
forall s a. Getting Any s a -> s -> Bool
has Getting Any Error e
g Error
err then () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure () else Env' withAuth -> (Finality, Request a, Error) -> IO ()
Hook_ (Finality, Request a, Error)
oldHook Env' withAuth
env (Finality, Request a, Error)
t

-- | Remove all error hooks for one specific AWS request
-- type. Designed to be used with 'errorHook'.
--
-- @since 2.1
removeErrorHooksFor ::
  forall a b.
  (AWSRequest a, AWSRequest b) =>
  Hook_ (Finality, Request b, Error) ->
  Hook_ (Finality, Request b, Error)
removeErrorHooksFor :: forall a b.
(AWSRequest a, AWSRequest b) =>
Hook_ (Finality, Request b, Error)
-> Hook_ (Finality, Request b, Error)
removeErrorHooksFor = forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ @(Finality, Request a, Error)

-- | Turn a @'Hook' a@ into another @'Hook' a@ that does nothing.
--
-- @
-- -- Example: remove all request hooks:
-- requestHook noHook :: Hooks -> Hooks
-- @
--
-- @since 2.0
noHook :: Hook a -> Hook a
noHook :: forall a. Hook a -> Hook a
noHook Hook a
_ Env' withAuth
_ = a -> IO a
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | Turn a @'Hook_' a@ into another @'Hook_' a@ that does nothing.
--
-- @
-- -- Example: Remove all response hooks:
-- responseHook noHook_ :: Hooks -> Hooks
-- @
--
-- @since 2.0
noHook_ :: Hook_ a -> Hook_ a
noHook_ :: forall a. Hook_ a -> Hook_ a
noHook_ Hook_ a
_ Env' withAuth
_ a
_ = () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Add default logging hooks. The default 'Env'' from
-- 'Amazonka.Env.newEnv' already has logging hooks installed, so you
-- probably only want this if you are building your own 'Hooks' from
-- scratch.
--
-- @since 2.0
addLoggingHooks :: Hooks -> Hooks
addLoggingHooks :: Hooks -> Hooks
addLoggingHooks
  hooks :: Hooks
hooks@Hooks
    { forall a. AWSRequest a => Hook_ (Signed a)
signedRequest :: Hooks -> forall a. AWSRequest a => Hook_ (Signed a)
signedRequest :: forall a. AWSRequest a => Hook_ (Signed a)
signedRequest,
      Hook ClientRequest
clientRequest :: Hooks -> Hook ClientRequest
clientRequest :: Hook ClientRequest
clientRequest,
      forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse :: Hooks
-> forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse :: forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse,
      Hook ByteStringLazy
rawResponseBody :: Hooks -> Hook ByteStringLazy
rawResponseBody :: Hook ByteStringLazy
rawResponseBody,
      forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry :: Hooks
-> forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry :: forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry,
      forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry :: Hooks
-> forall a.
   AWSRequest a =>
   Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry :: forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry,
      forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error :: Hooks
-> forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error :: forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error
    } =
    Hooks
hooks
      { signedRequest = \env :: Env' withAuth
env@Env {Logger
logger :: Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger} s :: Signed a
s@Signed {Meta
signedMeta :: Meta
signedMeta :: forall a. Signed a -> Meta
signedMeta} -> do
          Env' withAuth -> Signed a -> IO ()
forall a. AWSRequest a => Hook_ (Signed a)
Hook_ (Signed a)
signedRequest Env' withAuth
env Signed a
s
          Logger -> Meta -> IO ()
forall (m :: * -> *) a. (MonadIO m, ToLog a) => Logger -> a -> m ()
logTrace Logger
logger Meta
signedMeta,
        clientRequest = \env :: Env' withAuth
env@Env {Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger :: Logger
logger} ClientRequest
rq -> do
          rq' <- Env' withAuth -> ClientRequest -> IO ClientRequest
Hook ClientRequest
clientRequest Env' withAuth
env ClientRequest
rq
          rq' <$ logDebug logger rq',
        clientResponse = \env :: Env' withAuth
env@Env {Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger :: Logger
logger} t :: (Request a, ClientResponse ())
t@(Request a
_, ClientResponse ()
rs) -> do
          Env' withAuth -> (Request a, ClientResponse ()) -> IO ()
forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
Hook_ (Request a, ClientResponse ())
clientResponse Env' withAuth
env (Request a, ClientResponse ())
t
          Logger -> ClientResponse () -> IO ()
forall (m :: * -> *) a. (MonadIO m, ToLog a) => Logger -> a -> m ()
logDebug Logger
logger ClientResponse ()
rs,
        rawResponseBody = \env :: Env' withAuth
env@Env {Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger :: Logger
logger} ByteStringLazy
body -> do
          body' <- Env' withAuth -> ByteStringLazy -> IO ByteStringLazy
Hook ByteStringLazy
rawResponseBody Env' withAuth
env ByteStringLazy
body
          body' <$ logTrace logger ("[Raw Response Body] {\n" <> body' <> "\n}"),
        requestRetry = \env :: Env' withAuth
env@Env {Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger :: Logger
logger} t :: (Request a, Text, RetryStatus)
t@(Request a
_, Text
name, RetryStatus
retryStatus) -> do
          Env' withAuth -> (Request a, Text, RetryStatus) -> IO ()
forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
Hook_ (Request a, Text, RetryStatus)
requestRetry Env' withAuth
env (Request a, Text, RetryStatus)
t
          Logger -> ByteStringBuilder -> IO ()
forall (m :: * -> *) a. (MonadIO m, ToLog a) => Logger -> a -> m ()
logDebug Logger
logger
            (ByteStringBuilder -> IO ())
-> ([ByteStringBuilder] -> ByteStringBuilder)
-> [ByteStringBuilder]
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteStringBuilder] -> ByteStringBuilder
munwords
            ([ByteStringBuilder] -> IO ()) -> [ByteStringBuilder] -> IO ()
forall a b. (a -> b) -> a -> b
$ [ ByteStringBuilder
"[Retry " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Text
name ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
"]",
                ByteStringBuilder
"after",
                Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (RetryStatus -> Int
Retry.rsIterNumber RetryStatus
retryStatus Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1),
                ByteStringBuilder
"attempt(s)."
              ],
        awaitRetry = \env :: Env' withAuth
env@Env {Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger :: Logger
logger} t :: (Request a, Wait a, Accept, RetryStatus)
t@(Request a
_, Wait {ByteString
name :: ByteString
name :: forall a. Wait a -> ByteString
name}, Accept
accept, RetryStatus
retryStatus) -> do
          Env' withAuth -> (Request a, Wait a, Accept, RetryStatus) -> IO ()
forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry Env' withAuth
env (Request a, Wait a, Accept, RetryStatus)
t
          Logger -> ByteStringBuilder -> IO ()
forall (m :: * -> *) a. (MonadIO m, ToLog a) => Logger -> a -> m ()
logDebug Logger
logger
            (ByteStringBuilder -> IO ())
-> ([ByteStringBuilder] -> ByteStringBuilder)
-> [ByteStringBuilder]
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteStringBuilder] -> ByteStringBuilder
munwords
            ([ByteStringBuilder] -> IO ()) -> [ByteStringBuilder] -> IO ()
forall a b. (a -> b) -> a -> b
$ [ ByteStringBuilder
"[Await " ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteString -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build ByteString
name ByteStringBuilder -> ByteStringBuilder -> ByteStringBuilder
forall a. Semigroup a => a -> a -> a
<> ByteStringBuilder
"]",
                Accept -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build Accept
accept,
                ByteStringBuilder
"after",
                Int -> ByteStringBuilder
forall a. ToLog a => a -> ByteStringBuilder
build (RetryStatus -> Int
Retry.rsIterNumber RetryStatus
retryStatus Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1),
                ByteStringBuilder
"attempts."
              ],
        error = \env :: Env' withAuth
env@Env {Logger
logger :: forall (withAuth :: * -> *). Env' withAuth -> Logger
logger :: Logger
logger} t :: (Finality, Request a, Error)
t@(Finality
finality, Request a
_, Error
err) -> do
          Env' withAuth -> (Finality, Request a, Error) -> IO ()
forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
Hook_ (Finality, Request a, Error)
error Env' withAuth
env (Finality, Request a, Error)
t
          case Finality
finality of
            Finality
NotFinal -> Logger -> Error -> IO ()
forall (m :: * -> *) a. (MonadIO m, ToLog a) => Logger -> a -> m ()
logDebug Logger
logger Error
err
            Finality
Final -> Logger -> Error -> IO ()
forall (m :: * -> *) a. (MonadIO m, ToLog a) => Logger -> a -> m ()
logError Logger
logger Error
err
      }
    where
      munwords :: [ByteStringBuilder] -> ByteStringBuilder
munwords = [ByteStringBuilder] -> ByteStringBuilder
forall a. Monoid a => [a] -> a
mconcat ([ByteStringBuilder] -> ByteStringBuilder)
-> ([ByteStringBuilder] -> [ByteStringBuilder])
-> [ByteStringBuilder]
-> ByteStringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStringBuilder -> [ByteStringBuilder] -> [ByteStringBuilder]
forall a. a -> [a] -> [a]
intersperse ByteStringBuilder
" "

-- | Empty 'Hooks' structure which returns everything unmodified.
--
-- @since 2.0
noHooks :: Hooks
noHooks :: Hooks
noHooks =
  Hooks
    { request :: forall a. AWSRequest a => Hook a
request = (a -> IO a) -> Env' withAuth -> a -> IO a
forall a b. a -> b -> a
const a -> IO a
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure,
      configuredRequest :: forall a. AWSRequest a => Hook (Request a)
configuredRequest = (Request a -> IO (Request a))
-> Env' withAuth -> Request a -> IO (Request a)
forall a b. a -> b -> a
const Request a -> IO (Request a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure,
      wait :: forall a. AWSRequest a => Hook (Wait a)
wait = (Wait a -> IO (Wait a)) -> Env' withAuth -> Wait a -> IO (Wait a)
forall a b. a -> b -> a
const Wait a -> IO (Wait a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure,
      signedRequest :: forall a. AWSRequest a => Hook_ (Signed a)
signedRequest = \Env' withAuth
_ Signed a
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
      clientRequest :: Hook ClientRequest
clientRequest = (ClientRequest -> IO ClientRequest)
-> Env' withAuth -> ClientRequest -> IO ClientRequest
forall a b. a -> b -> a
const ClientRequest -> IO ClientRequest
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure,
      clientResponse :: forall a. AWSRequest a => Hook_ (Request a, ClientResponse ())
clientResponse = \Env' withAuth
_ (Request a, ClientResponse ())
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
      rawResponseBody :: Hook ByteStringLazy
rawResponseBody = (ByteStringLazy -> IO ByteStringLazy)
-> Env' withAuth -> ByteStringLazy -> IO ByteStringLazy
forall a b. a -> b -> a
const ByteStringLazy -> IO ByteStringLazy
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure,
      requestRetry :: forall a. AWSRequest a => Hook_ (Request a, Text, RetryStatus)
requestRetry = \Env' withAuth
_ (Request a, Text, RetryStatus)
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
      awaitRetry :: forall a.
AWSRequest a =>
Hook_ (Request a, Wait a, Accept, RetryStatus)
awaitRetry = \Env' withAuth
_ (Request a, Wait a, Accept, RetryStatus)
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
      response :: forall a.
AWSRequest a =>
Hook_ (Request a, ClientResponse (AWSResponse a))
response = \Env' withAuth
_ (Request a, ClientResponse (AWSResponse a))
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
      error :: forall a. AWSRequest a => Hook_ (Finality, Request a, Error)
error = \Env' withAuth
_ (Finality, Request a, Error)
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    }

-- | Unconditionally add a @'Hook' a@ to the chain of hooks. If you
-- need to do something with specific request types, you want
-- 'addHookFor', instead.
--
-- __NOTE__: This function has been deprecated because it's almost
-- impossible to do anything useful with. Instead, you should use one
-- of the hook-specific functions in this module.
--
-- @since 2.0
addHook :: Hook a -> Hook a -> Hook a
addHook :: forall a. Hook a -> Hook a -> Hook a
addHook Hook a
newHook Hook a
oldHook Env' withAuth
env = Env' withAuth -> a -> IO a
Hook a
oldHook Env' withAuth
env (a -> IO a) -> (a -> IO a) -> a -> IO a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Env' withAuth -> a -> IO a
Hook a
newHook Env' withAuth
env
{-# DEPRECATED addHook "this function will be internal in Amazonka 2.2" #-}

-- | Unconditionally add a @'Hook_' a@ to the chain of hooks. If you
-- need to do something with specific request types, you want
-- 'addHookFor_', instead.
--
-- __NOTE__: This function has been deprecated because it's almost
-- impossible to do anything useful with. Instead, you should use one
-- of the hook-specific functions in this module.
--
-- @since 2.0
addHook_ :: Hook_ a -> Hook_ a -> Hook_ a
addHook_ :: forall a. Hook_ a -> Hook_ a -> Hook_ a
addHook_ Hook_ a
newHook Hook_ a
oldHook Env' withAuth
env a
a = Env' withAuth -> a -> IO ()
Hook_ a
oldHook Env' withAuth
env a
a IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Env' withAuth -> a -> IO ()
Hook_ a
newHook Env' withAuth
env a
a
{-# DEPRECATED addHook_ "this function will be internal in Amazonka 2.2" #-}

-- | Like 'addHook', adds an unconditional hook, but it also captures
-- the @'AWSRequest' a@ constraint.
--
-- __NOTE__: This function has been deprecated because it's very easy
-- to accidentally write code which typechecks but never fires the new
-- hook. Instead, you should use one of the hook-specific functions in
-- this module.
--
-- @since 2.0
addAWSRequestHook :: (AWSRequest a) => Hook a -> Hook a -> Hook a
addAWSRequestHook :: forall a. AWSRequest a => Hook a -> Hook a -> Hook a
addAWSRequestHook = Hook a -> Hook a -> Env' withAuth -> a -> IO a
Hook a -> Hook a -> Hook a
forall a. Hook a -> Hook a -> Hook a
addHook
{-# DEPRECATED addAWSRequestHook "this function will be removed in Amazonka 2.2" #-}

-- | 'addAWSRequestHook_' is 'addAWSRequestHook' but for 'Hook_'s.
--
-- __NOTE__: This function has been deprecated because it's very easy
-- to accidentally write code which typechecks but never fires the new
-- hook. Instead, you should use one of the hook-specific functions in
-- this module.
--
-- @since 2.0
addAWSRequestHook_ :: (AWSRequest a) => Hook_ a -> Hook_ a -> Hook_ a
addAWSRequestHook_ :: forall a. AWSRequest a => Hook_ a -> Hook_ a -> Hook_ a
addAWSRequestHook_ = Hook_ a -> Hook_ a -> Env' withAuth -> a -> IO ()
Hook_ a -> Hook_ a -> Hook_ a
forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_
{-# DEPRECATED addAWSRequestHook_ "this function will be removed in Amazonka 2.2" #-}

-- | @addHookFor \@a newHook oldHook@ When @a@ and @b@ are the same
-- type, run the given 'Hook a' after all others, otherwise only run
-- the existing hooks.
--
-- @
-- -- Example: Run @getObjectRequestHook@ on anything that is a @GetObjectRequest@:
-- requestHook (addHookFor @GetObjectRequest getObjectRequestHook) :: Hooks -> Hooks
-- @
--
-- __NOTE__: This function has been deprecated because it's very easy
-- to accidentally write code which typechecks but never fires the new
-- hook. Instead, you should use one of the hook-specific functions in
-- this module.
--
-- @since 2.0
addHookFor ::
  forall a b. (Typeable a, Typeable b) => Hook a -> Hook b -> Hook b
addHookFor :: forall a b. (Typeable a, Typeable b) => Hook a -> Hook b -> Hook b
addHookFor Hook a
newHook Hook b
oldHook Env' withAuth
env =
  Env' withAuth -> b -> IO b
Hook b
oldHook Env' withAuth
env (b -> IO b) -> (b -> IO b) -> b -> IO b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> case forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @a @b of
    Just a :~: b
Refl -> Env' withAuth -> a -> IO a
Hook a
newHook Env' withAuth
env
    Maybe (a :~: b)
Nothing -> b -> IO b
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# DEPRECATED addHookFor "this function will be internal in Amazonka 2.2" #-}

-- | When @a@ and @b@ are the same type, run the given 'Hook_ a' after
-- all other hooks have run.
--
-- @
-- -- Example: Run @aSignedRequestHook@ on anything that is a @Signed GetObjectRequest@:
-- requestHook (addHookFor_ @(Signed GetObjectRequest) aSignedRequestHook) :: Hooks -> Hooks
-- @
--
-- __NOTE__: This function has been deprecated because it's very easy
-- to accidentally write code which typechecks but never fires the new
-- hook. Instead, you should use one of the hook-specific functions in
-- this module.
--
-- @since 2.0
addHookFor_ ::
  forall a b. (Typeable a, Typeable b) => Hook_ a -> Hook_ b -> Hook_ b
addHookFor_ :: forall a b.
(Typeable a, Typeable b) =>
Hook_ a -> Hook_ b -> Hook_ b
addHookFor_ Hook_ a
newHook Hook_ b
oldHook Env' withAuth
env b
a = do
  Env' withAuth -> b -> IO ()
Hook_ b
oldHook Env' withAuth
env b
a
  case forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @a @b of
    Just a :~: b
Refl -> Env' withAuth -> a -> IO ()
Hook_ a
newHook Env' withAuth
env a
b
a
    Maybe (a :~: b)
Nothing -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
{-# DEPRECATED addHookFor_ "this function will be internal in Amazonka 2.2" #-}

-- | When @a@ and @b@ are the same type, do not call any more hooks.
--
-- @
-- -- Example: Prevent any request hooks from running against a @PutObjectRequest@:
-- requestHook (removeHooksFor @PutObjectRequest) :: Hooks -> Hooks
-- @
--
-- __NOTE__: This function has been deprecated because it's very easy
-- to accidentally write code which typechecks but never suppresses
-- the hook. Instead, you should use one of the hook-specific
-- functions in this module.
--
-- @since 2.0
removeHooksFor :: forall a b. (Typeable a, Typeable b) => Hook b -> Hook b
removeHooksFor :: forall a b. (Typeable a, Typeable b) => Hook b -> Hook b
removeHooksFor Hook b
oldHook Env' withAuth
env = case forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @a @b of
  Just a :~: b
Refl -> b -> IO b
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  Maybe (a :~: b)
Nothing -> Env' withAuth -> b -> IO b
Hook b
oldHook Env' withAuth
env
{-# DEPRECATED removeHooksFor "this function will be internal in Amazonka 2.2" #-}

-- | When @a@ and @b@ are the same type, do not call any more hooks.
--
-- @
-- -- Example: Prevent any error hooks from running against errors caused by a @PutObjectRequest@:
-- errorHook (removeHooksFor @(Finality, Request PutObjectRequest, Error)) :: Hooks -> Hooks
-- @
--
-- __NOTE__: This function has been deprecated because it's very easy
-- to accidentally write code which typechecks but never suppresses
-- the hook. Instead, you should use one of the hook-specific
-- functions in this module.
--
-- @since 2.0
removeHooksFor_ :: forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ :: forall a b. (Typeable a, Typeable b) => Hook_ b -> Hook_ b
removeHooksFor_ Hook_ b
oldHook Env' withAuth
env b
a = case forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @a @b of
  Just a :~: b
Refl -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  Maybe (a :~: b)
Nothing -> Env' withAuth -> b -> IO ()
Hook_ b
oldHook Env' withAuth
env b
a
{-# DEPRECATED removeHooksFor_ "this function will be internal in Amazonka 2.2" #-}