Add lookupResponseHeader

This commit is contained in:
Dan Burton 2018-10-28 01:33:39 -04:00
parent 79bbcaf819
commit e604b930dc
No known key found for this signature in database
GPG key ID: 41F154F410EC12E0
2 changed files with 30 additions and 1 deletions

View file

@ -112,7 +112,7 @@ import Servant.API.ResponseHeaders
(AddHeader, BuildHeadersTo (buildHeadersTo), (AddHeader, BuildHeadersTo (buildHeadersTo),
GetHeaders (getHeaders), HList (..), Headers (..), GetHeaders (getHeaders), HList (..), Headers (..),
ResponseHeader (..), addHeader, getHeadersHList, getResponse, ResponseHeader (..), addHeader, getHeadersHList, getResponse,
noHeader) noHeader, HasResponseHeader, lookupResponseHeader)
import Servant.API.Stream import Servant.API.Stream
(BoundaryStrategy (..), ByteStringParser (..), (BoundaryStrategy (..), ByteStringParser (..),
FramingRender (..), FramingUnrender (..), FramingRender (..), FramingUnrender (..),

View file

@ -26,6 +26,8 @@ module Servant.API.ResponseHeaders
, AddHeader , AddHeader
, addHeader , addHeader
, noHeader , noHeader
, HasResponseHeader
, lookupResponseHeader
, BuildHeadersTo(buildHeadersTo) , BuildHeadersTo(buildHeadersTo)
, GetHeaders(getHeaders) , GetHeaders(getHeaders)
, GetHeaders' , GetHeaders'
@ -183,6 +185,33 @@ addHeader = addOptionalHeader . Header
noHeader :: AddHeader h v orig new => orig -> new noHeader :: AddHeader h v orig new => orig -> new
noHeader = addOptionalHeader MissingHeader noHeader = addOptionalHeader MissingHeader
class HasResponseHeader h a headers where
hlistLookupHeader :: HList headers -> ResponseHeader h a
instance {-# OVERLAPPING #-} HasResponseHeader h a (Header h a ': rest) where
hlistLookupHeader (HCons ha _) = ha
instance {-# OVERLAPPABLE #-} (HasResponseHeader h a rest) => HasResponseHeader h a (first ': rest) where
hlistLookupHeader (HCons _ hs) = hlistLookupHeader hs
-- | Look up a specific ResponseHeader,
-- without having to know what position it is in the HList.
--
-- >>> let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String
-- >>> let example2 = addHeader True example1 :: Headers '[Header "1st" Bool, Header "someheader" Int] String
-- >>> lookupResponseHeader example2 :: ResponseHeader "someheader" Int
-- Header 5
-- >>> lookupResponseHeader example2 :: ResponseHeader "1st" Bool
-- Header True
--
-- Usage of this function relies on an explicit type annotation of the header to be looked up.
-- This can be done with type annotations on the result, or with an explicit type application.
-- e.g.
-- @lookupResponseHeader \@"someheader" example2@
lookupResponseHeader :: (HasResponseHeader h a headers)
=> Headers headers r -> ResponseHeader h a
lookupResponseHeader = hlistLookupHeader . getHeadersHList
-- $setup -- $setup
-- >>> import Servant.API -- >>> import Servant.API
-- >>> import Data.Aeson -- >>> import Data.Aeson