amazonka-core-2.0: src/Amazonka/Waiter.hs
-- |
-- Module : Amazonka.Waiter
-- Copyright : (c) 2013-2023 Brendan Hay
-- License : Mozilla Public License, v. 2.0.
-- Maintainer : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
-- Stability : provisional
-- Portability : non-portable (GHC extensions)
module Amazonka.Waiter
( -- * Types
Acceptor,
Accept (..),
Wait (..),
-- ** Lenses
wait_name,
wait_attempts,
wait_delay,
wait_acceptors,
-- * Acceptors
accept,
-- * Matchers
matchAll,
matchAny,
matchNonEmpty,
matchError,
matchStatus,
-- * Util
nonEmptyText,
)
where
import Amazonka.Core.Lens.Internal
( Fold,
Lens,
allOf,
anyOf,
to,
(^..),
(^?),
)
import Amazonka.Data
import Amazonka.Error (_HttpStatus)
import Amazonka.Prelude
import Amazonka.Types
import qualified Data.Text as Text
import qualified Network.HTTP.Client as Client
type Acceptor a = Request a -> Either Error (ClientResponse (AWSResponse a)) -> Maybe Accept
data Accept
= AcceptSuccess
| AcceptFailure
| AcceptRetry
deriving stock (Eq, Show)
instance ToLog Accept where
build = \case
AcceptSuccess -> "Success"
AcceptFailure -> "Failure"
AcceptRetry -> "Retry"
-- | Timing and acceptance criteria to check fulfillment of a remote operation.
data Wait a = Wait
{ name :: ByteString,
attempts :: Int,
delay :: Seconds,
acceptors :: [Acceptor a]
}
{-# INLINE wait_name #-}
wait_name :: Lens' (Wait a) ByteString
wait_name f w@Wait {name} = f name <&> \name' -> w {name = name'}
{-# INLINE wait_attempts #-}
wait_attempts :: forall a. Lens' (Wait a) Int
wait_attempts f w@Wait {attempts} = f attempts <&> \attempts' -> (w :: Wait a) {attempts = attempts'}
{-# INLINE wait_delay #-}
wait_delay :: Lens' (Wait a) Seconds
wait_delay f w@Wait {delay} = f delay <&> \delay' -> w {delay = delay'}
{-# INLINE wait_acceptors #-}
wait_acceptors :: Lens (Wait a) (Wait b) [Acceptor a] [Acceptor b]
wait_acceptors f w@Wait {acceptors} = f acceptors <&> \acceptors' -> w {acceptors = acceptors'}
accept :: Wait a -> Acceptor a
accept w rq rs = listToMaybe . mapMaybe (\f -> f rq rs) $ acceptors w
matchAll :: Eq b => b -> Accept -> Fold (AWSResponse a) b -> Acceptor a
matchAll x a l = match (allOf l (== x)) a
matchAny :: Eq b => b -> Accept -> Fold (AWSResponse a) b -> Acceptor a
matchAny x a l = match (anyOf l (== x)) a
matchNonEmpty :: Bool -> Accept -> Fold (AWSResponse a) b -> Acceptor a
matchNonEmpty x a l = match (\rs -> null (rs ^.. l) == x) a
matchStatus :: Int -> Accept -> Acceptor a
matchStatus x a _ = \case
Right rs | x == fromEnum (Client.responseStatus rs) -> Just a
Left e | Just x == (fromEnum <$> e ^? _HttpStatus) -> Just a
_ -> Nothing
matchError :: ErrorCode -> Accept -> Acceptor a
matchError c a _ = \case
Left e | Just c == e ^? _ServiceError . to code -> Just a
_ -> Nothing
match :: (AWSResponse a -> Bool) -> Accept -> Acceptor a
match f a _ = \case
Right rs | f (Client.responseBody rs) -> Just a
_ -> Nothing
nonEmptyText :: Fold a Text -> Fold a Bool
nonEmptyText f = f . to Text.null