    module Network.HTTP.Client.Contrib where

    import Data.Aeson
    import Data.Bifunctor
    import Data.ByteString.Lazy.Char8 qualified as BSL
    import Network.HTTP.Conduit
    import Network.HTTP.Types qualified as HT

    -- | Get response body out of a @Response@
    handleResponse :: Response BSL.ByteString -> Either BSL.ByteString BSL.ByteString
    handleResponse :: Response ByteString -> Either ByteString ByteString
    handleResponse Response ByteString
    rsp
      | Status -> Bool
    HT.statusIsSuccessful (Response ByteString -> Status
    forall body. Response body -> Status
    responseStatus Response ByteString
    rsp) = ByteString -> Either ByteString ByteString
    forall a b. b -> Either a b
    Right (Response ByteString -> ByteString
    forall body. Response body -> body
    responseBody Response ByteString
    rsp)
      -- TODO: better to surface up entire resp so that client can decide what to do when error happens.
      -- e.g. when 404, the response body could be empty hence library user has no idea what's happening.
      -- Which will be breaking changes.
      -- The current work around is surface up entire response as string.
      | ByteString -> Bool
    BSL.null (Response ByteString -> ByteString
    forall body. Response body -> body
    responseBody Response ByteString
    rsp) = ByteString -> Either ByteString ByteString
    forall a b. a -> Either a b
    Left ([Char] -> ByteString
    BSL.pack ([Char] -> ByteString) -> [Char] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Response ByteString -> [Char]
    forall a. Show a => a -> [Char]
    show Response ByteString
    rsp)
      | Bool
    otherwise = ByteString -> Either ByteString ByteString
    forall a b. a -> Either a b
    Left (Response ByteString -> ByteString
    forall body. Response body -> body
    responseBody Response ByteString
    rsp)

    handleResponseJSON ::
      FromJSON a =>
      Response BSL.ByteString ->
      Either BSL.ByteString a
    handleResponseJSON :: forall a. FromJSON a => Response ByteString -> Either ByteString a
    handleResponseJSON =
      (ByteString -> Either ByteString a)
    -> (ByteString -> Either ByteString a)
    -> Either ByteString ByteString
    -> Either ByteString a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either ByteString -> Either ByteString a
    forall a b. a -> Either a b
    Left (([Char] -> ByteString) -> Either [Char] a -> Either ByteString a
    forall a b c. (a -> b) -> Either a c -> Either b c
    forall (p :: * -> * -> *) a b c.
    Bifunctor p =>
    (a -> b) -> p a c -> p b c
    first [Char] -> ByteString
    BSL.pack (Either [Char] a -> Either ByteString a)
    -> (ByteString -> Either [Char] a)
    -> ByteString
    -> Either ByteString a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Either [Char] a
    forall a. FromJSON a => ByteString -> Either [Char] a
    eitherDecode) (Either ByteString ByteString -> Either ByteString a)
    -> (Response ByteString -> Either ByteString ByteString)
    -> Response ByteString
    -> Either ByteString a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Response ByteString -> Either ByteString ByteString
    handleResponse