waiz-0.0.1.0: src/Network/Wai/Optics/Response.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -Wall #-}
-- | Classy optics and constructor prisms for 'Response'.
module Network.Wai.Optics.Response (
-- * Classy optics
GetResponse (..),
HasResponse (..),
ReviewResponse (..),
AsResponse (..),
-- * Constructor prisms
-- ** ResponseFile
ReviewResponseFile (..),
AsResponseFile (..),
-- ** ResponseBuilder
ReviewResponseBuilder (..),
AsResponseBuilder (..),
-- ** ResponseStream
ReviewResponseStream (..),
AsResponseStream (..),
-- ** ResponseRaw
ReviewResponseRaw (..),
AsResponseRaw (..),
-- * Getters
responseStatus,
responseHeaders,
) where
import Control.Category (id)
import Control.Lens (Getter, Lens', Prism', Review, lens, prism', review, to, unto, view)
import Data.ByteString (ByteString)
import Data.ByteString.Builder (Builder)
import Data.Maybe (Maybe (..))
import Network.HTTP.Types (ResponseHeaders, Status)
import Network.Wai (Response, StreamingBody)
import qualified Network.Wai as Wai
import Network.Wai.Internal (
FilePart,
Response (..),
)
import Prelude (FilePath, IO, const, flip, uncurry)
-- | Type class for values that can be viewed as a 'Response'.
class GetResponse s where
-- | A 'Getter' to obtain a 'Response'.
getResponse :: Getter s Response
instance GetResponse Response where
getResponse = id
{-# INLINE getResponse #-}
-- | Type class for values with a lens into a 'Response'.
class (GetResponse s) => HasResponse s where
{-# MINIMAL setResponse #-}
-- | Replace the 'Response' component.
setResponse :: Response -> s -> s
-- | A 'Lens'' into the 'Response' component.
response :: Lens' s Response
response = lens (view getResponse) (flip setResponse)
{-# INLINE response #-}
instance HasResponse Response where
setResponse = const
{-# INLINE setResponse #-}
-- | Type class for values that can be constructed from a 'Response'.
class ReviewResponse t where
-- | A 'Review' to construct a value from a 'Response'.
reviewResponse :: Review t Response
instance ReviewResponse Response where
reviewResponse = unto id
{-# INLINE reviewResponse #-}
-- | Type class for values with a prism into a 'Response'.
class (ReviewResponse t) => AsResponse t where
{-# MINIMAL matchResponse #-}
-- | Attempt to extract a 'Response'.
matchResponse :: t -> Maybe Response
-- | A 'Prism'' into a 'Response'.
_Response :: Prism' t Response
_Response = prism' (review reviewResponse) matchResponse
{-# INLINE _Response #-}
instance AsResponse Response where
matchResponse = Just
{-# INLINE matchResponse #-}
-- | A 'Getter' on the 'Status' of a 'Response'.
responseStatus :: Getter Response Status
responseStatus = to Wai.responseStatus
{-# INLINE responseStatus #-}
-- | A 'Getter' on the 'ResponseHeaders' of a 'Response'.
responseHeaders :: Getter Response ResponseHeaders
responseHeaders = to Wai.responseHeaders
{-# INLINE responseHeaders #-}
-- ** ResponseFile
-- | Type class for values that can be constructed from a @ResponseFile@.
class ReviewResponseFile t where
-- | A 'Review' to construct a value from @ResponseFile@ components.
reviewResponseFile :: Review t (Status, ResponseHeaders, FilePath, Maybe FilePart)
instance ReviewResponseFile Response where
reviewResponseFile = unto (\(s, h, fp, mfp) -> ResponseFile s h fp mfp)
{-# INLINE reviewResponseFile #-}
-- | Type class for values with a prism into a @ResponseFile@.
class (ReviewResponseFile t) => AsResponseFile t where
{-# MINIMAL matchResponseFile #-}
-- | Attempt to extract @ResponseFile@ components.
matchResponseFile :: t -> Maybe (Status, ResponseHeaders, FilePath, Maybe FilePart)
-- | A 'Prism'' into @ResponseFile@ components.
_ResponseFile :: Prism' t (Status, ResponseHeaders, FilePath, Maybe FilePart)
_ResponseFile = prism' (review reviewResponseFile) matchResponseFile
{-# INLINE _ResponseFile #-}
instance AsResponseFile Response where
matchResponseFile = \case
ResponseFile s h fp mfp -> Just (s, h, fp, mfp)
_ -> Nothing
{-# INLINE matchResponseFile #-}
-- ** ResponseBuilder
-- | Type class for values that can be constructed from a @ResponseBuilder@.
class ReviewResponseBuilder t where
-- | A 'Review' to construct a value from @ResponseBuilder@ components.
reviewResponseBuilder :: Review t (Status, ResponseHeaders, Builder)
instance ReviewResponseBuilder Response where
reviewResponseBuilder = unto (\(s, h, b) -> ResponseBuilder s h b)
{-# INLINE reviewResponseBuilder #-}
-- | Type class for values with a prism into a @ResponseBuilder@.
class (ReviewResponseBuilder t) => AsResponseBuilder t where
{-# MINIMAL matchResponseBuilder #-}
-- | Attempt to extract @ResponseBuilder@ components.
matchResponseBuilder :: t -> Maybe (Status, ResponseHeaders, Builder)
-- | A 'Prism'' into @ResponseBuilder@ components.
_ResponseBuilder :: Prism' t (Status, ResponseHeaders, Builder)
_ResponseBuilder = prism' (review reviewResponseBuilder) matchResponseBuilder
{-# INLINE _ResponseBuilder #-}
instance AsResponseBuilder Response where
matchResponseBuilder = \case
ResponseBuilder s h b -> Just (s, h, b)
_ -> Nothing
{-# INLINE matchResponseBuilder #-}
-- ** ResponseStream
-- | Type class for values that can be constructed from a @ResponseStream@.
class ReviewResponseStream t where
-- | A 'Review' to construct a value from @ResponseStream@ components.
reviewResponseStream :: Review t (Status, ResponseHeaders, StreamingBody)
instance ReviewResponseStream Response where
reviewResponseStream = unto (\(s, h, sb) -> ResponseStream s h sb)
{-# INLINE reviewResponseStream #-}
-- | Type class for values with a prism into a @ResponseStream@.
class (ReviewResponseStream t) => AsResponseStream t where
{-# MINIMAL matchResponseStream #-}
-- | Attempt to extract @ResponseStream@ components.
matchResponseStream :: t -> Maybe (Status, ResponseHeaders, StreamingBody)
-- | A 'Prism'' into @ResponseStream@ components.
_ResponseStream :: Prism' t (Status, ResponseHeaders, StreamingBody)
_ResponseStream = prism' (review reviewResponseStream) matchResponseStream
{-# INLINE _ResponseStream #-}
instance AsResponseStream Response where
matchResponseStream = \case
ResponseStream s h sb -> Just (s, h, sb)
_ -> Nothing
{-# INLINE matchResponseStream #-}
-- ** ResponseRaw
-- | Type class for values that can be constructed from a @ResponseRaw@.
class ReviewResponseRaw t where
-- | A 'Review' to construct a value from @ResponseRaw@ components.
reviewResponseRaw :: Review t (IO ByteString -> (ByteString -> IO ()) -> IO (), Response)
instance ReviewResponseRaw Response where
reviewResponseRaw = unto (uncurry ResponseRaw)
{-# INLINE reviewResponseRaw #-}
-- | Type class for values with a prism into a @ResponseRaw@.
class (ReviewResponseRaw t) => AsResponseRaw t where
{-# MINIMAL matchResponseRaw #-}
-- | Attempt to extract @ResponseRaw@ components.
matchResponseRaw :: t -> Maybe (IO ByteString -> (ByteString -> IO ()) -> IO (), Response)
-- | A 'Prism'' into @ResponseRaw@ components.
_ResponseRaw :: Prism' t (IO ByteString -> (ByteString -> IO ()) -> IO (), Response)
_ResponseRaw = prism' (review reviewResponseRaw) matchResponseRaw
{-# INLINE _ResponseRaw #-}
instance AsResponseRaw Response where
matchResponseRaw = \case
ResponseRaw f r -> Just (f, r)
_ -> Nothing
{-# INLINE matchResponseRaw #-}