{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, DeriveDataTypeable, DeriveFunctor, TypeFamilies #-} module Aws.Response where import Data.IORef import Data.Monoid import Data.Attempt (Attempt(..)) import qualified Control.Exception as E import qualified Control.Failure as F import qualified Data.ByteString as B import qualified Data.Enumerator as En import qualified Network.HTTP.Enumerator as HTTP import qualified Network.HTTP.Types as HTTP data Response m a = Response m (Attempt a) deriving (Show, Functor) tellMetadata :: m -> Response m () tellMetadata m = Response m (return ()) instance Monoid m => Monad (Response m) where return x = Response mempty (Success x) Response m1 (Failure e) >>= _ = Response m1 (Failure e) Response m1 (Success x) >>= f = let Response m2 y = f x in Response (m1 `mappend` m2) y -- currently using First-semantics, Last SHOULD work too instance (Monoid m, E.Exception e) => F.Failure e (Response m) where failure e = Response mempty (F.failure e) tellMetadataRef :: Monoid m => IORef m -> m -> IO () tellMetadataRef r m = modifyIORef r (`mappend` m) class ResponseIteratee a where type ResponseMetadata a responseIteratee :: IORef (ResponseMetadata a) -> HTTP.Status -> HTTP.ResponseHeaders -> En.Iteratee B.ByteString IO a instance ResponseIteratee HTTP.Response where type ResponseMetadata HTTP.Response = () responseIteratee _ = HTTP.lbsIter